diff --git a/clang-tools-extra/clangd/SemanticHighlighting.h b/clang-tools-extra/clangd/SemanticHighlighting.h --- a/clang-tools-extra/clangd/SemanticHighlighting.h +++ b/clang-tools-extra/clangd/SemanticHighlighting.h @@ -28,8 +28,11 @@ LocalVariable, Parameter, Function, + FunctionDeclaration, Method, + MethodDeclaration, StaticMethod, + StaticMethodDeclaration, Field, StaticField, Class, 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 @@ -103,7 +103,7 @@ if (ND->getDeclName().getNameKind() != DeclarationName::Identifier) return true; - addToken(ND->getLocation(), ND); + addToken(ND->getLocation(), ND, /*IsDeclaration=*/true); return true; } @@ -186,7 +186,8 @@ addToken(Loc, TD); } - void addToken(SourceLocation Loc, const NamedDecl *D) { + void addToken(SourceLocation Loc, const NamedDecl *D, + bool IsDeclaration = false) { if (D->getDeclName().isIdentifier() && D->getName().empty()) // Don't add symbols that don't have any length. return; @@ -206,6 +207,11 @@ return; } if (auto *MD = dyn_cast(D)) { + if (IsDeclaration) { + addToken(Loc, MD->isStatic() ? HighlightingKind::StaticMethodDeclaration + : HighlightingKind::MethodDeclaration); + return; + } addToken(Loc, MD->isStatic() ? HighlightingKind::StaticMethod : HighlightingKind::Method); return; @@ -226,7 +232,7 @@ addToken(Loc, HighlightingKind::Parameter); return; } - if (const VarDecl *VD = dyn_cast(D)) { + if (auto *VD = dyn_cast(D)) { addToken(Loc, VD->isStaticDataMember() ? HighlightingKind::StaticField : VD->isLocalVarDecl() ? HighlightingKind::LocalVariable @@ -234,7 +240,8 @@ return; } if (isa(D)) { - addToken(Loc, HighlightingKind::Function); + addToken(Loc, IsDeclaration ? HighlightingKind::FunctionDeclaration + : HighlightingKind::Function); return; } if (isa(D)) { @@ -436,10 +443,16 @@ switch (Kind) { case HighlightingKind::Function: return "entity.name.function.cpp"; + case HighlightingKind::FunctionDeclaration: + return "entity.name.function.declaration.cpp"; case HighlightingKind::Method: return "entity.name.function.method.cpp"; + case HighlightingKind::MethodDeclaration: + return "entity.name.function.method.declaration.cpp"; case HighlightingKind::StaticMethod: return "entity.name.function.method.static.cpp"; + case HighlightingKind::StaticMethodDeclaration: + return "entity.name.function.method.static.declaration.cpp"; case HighlightingKind::Variable: return "variable.other.cpp"; case HighlightingKind::LocalVariable: diff --git a/clang-tools-extra/clangd/test/semantic-highlighting.test b/clang-tools-extra/clangd/test/semantic-highlighting.test --- a/clang-tools-extra/clangd/test/semantic-highlighting.test +++ b/clang-tools-extra/clangd/test/semantic-highlighting.test @@ -17,12 +17,21 @@ # CHECK-NEXT: "entity.name.function.cpp" # CHECK-NEXT: ], # CHECK-NEXT: [ +# CHECK-NEXT: "entity.name.function.declaration.cpp" +# CHECK-NEXT: ], +# CHECK-NEXT: [ # CHECK-NEXT: "entity.name.function.method.cpp" # CHECK-NEXT: ], # CHECK-NEXT: [ +# CHECK-NEXT: "entity.name.function.method.declaration.cpp" +# CHECK-NEXT: ], +# CHECK-NEXT: [ # CHECK-NEXT: "entity.name.function.method.static.cpp" # CHECK-NEXT: ], # CHECK-NEXT: [ +# CHECK-NEXT: "entity.name.function.method.static.declaration.cpp" +# CHECK-NEXT: ], +# CHECK-NEXT: [ # CHECK-NEXT: "variable.other.field.cpp" # CHECK-NEXT: ], # CHECK-NEXT: [ @@ -55,7 +64,7 @@ # CHECK-NEXT: "lines": [ # CHECK-NEXT: { # CHECK-NEXT: "line": 0, -# CHECK-NEXT: "tokens": "AAAAAAADAA0AAAAEAAEAAA==" +# CHECK-NEXT: "tokens": "AAAAAAADABAAAAAEAAEAAA==" # CHECK-NEXT: } # CHECK-NEXT: ], # CHECK-NEXT: "textDocument": { @@ -70,11 +79,11 @@ # CHECK-NEXT: "lines": [ # CHECK-NEXT: { # CHECK-NEXT: "line": 0, -# CHECK-NEXT: "tokens": "AAAAAAADAA0AAAAEAAEAAA==" +# CHECK-NEXT: "tokens": "AAAAAAADABAAAAAEAAEAAA==" # CHECK-NEXT: } # CHECK-NEXT: { # CHECK-NEXT: "line": 1, -# CHECK-NEXT: "tokens": "AAAAAAADAA0AAAAEAAEAAA==" +# CHECK-NEXT: "tokens": "AAAAAAADABAAAAAEAAEAAA==" # CHECK-NEXT: } # CHECK-NEXT: ], # CHECK-NEXT: "textDocument": { @@ -89,7 +98,7 @@ # CHECK-NEXT: "lines": [ # CHECK-NEXT: { # CHECK-NEXT: "line": 1, -# CHECK-NEXT: "tokens": "AAAAAAADAA0AAAAEAAEAAA==" +# CHECK-NEXT: "tokens": "AAAAAAADABAAAAAEAAEAAA==" # CHECK-NEXT: } # CHECK-NEXT: ], # CHECK-NEXT: "textDocument": { 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 @@ -38,6 +38,7 @@ {HighlightingKind::LocalVariable, "LocalVariable"}, {HighlightingKind::Parameter, "Parameter"}, {HighlightingKind::Function, "Function"}, + {HighlightingKind::FunctionDeclaration, "FunctionDeclaration"}, {HighlightingKind::Class, "Class"}, {HighlightingKind::Enum, "Enum"}, {HighlightingKind::Namespace, "Namespace"}, @@ -45,7 +46,9 @@ {HighlightingKind::Field, "Field"}, {HighlightingKind::StaticField, "StaticField"}, {HighlightingKind::Method, "Method"}, + {HighlightingKind::MethodDeclaration, "MethodDeclaration"}, {HighlightingKind::StaticMethod, "StaticMethod"}, + {HighlightingKind::StaticMethodDeclaration, "StaticMethodDeclaration"}, {HighlightingKind::TemplateParameter, "TemplateParameter"}, {HighlightingKind::Primitive, "Primitive"}}; std::vector ExpectedTokens; @@ -112,7 +115,7 @@ }; struct { } $Variable[[S]]; - $Primitive[[void]] $Function[[foo]]($Primitive[[int]] $Parameter[[A]], $Class[[AS]] $Parameter[[As]]) { + $Primitive[[void]] $FunctionDeclaration[[foo]]($Primitive[[int]] $Parameter[[A]], $Class[[AS]] $Parameter[[As]]) { $Primitive[[auto]] $LocalVariable[[VeryLongVariableName]] = 12312; $Class[[AS]] $LocalVariable[[AA]]; $Primitive[[auto]] $LocalVariable[[L]] = $LocalVariable[[AA]].$Field[[SomeMember]] + $Parameter[[A]]; @@ -121,13 +124,13 @@ } )cpp", R"cpp( - $Primitive[[void]] $Function[[foo]]($Primitive[[int]]); - $Primitive[[void]] $Function[[Gah]](); - $Primitive[[void]] $Function[[foo]]() { + $Primitive[[void]] $FunctionDeclaration[[foo]]($Primitive[[int]]); + $Primitive[[void]] $FunctionDeclaration[[Gah]](); + $Primitive[[void]] $FunctionDeclaration[[foo]]() { auto $LocalVariable[[Bou]] = $Function[[Gah]]; } struct $Class[[A]] { - $Primitive[[void]] $Method[[abc]](); + $Primitive[[void]] $MethodDeclaration[[abc]](); }; )cpp", R"cpp( @@ -151,7 +154,7 @@ }; $Class[[B]]::$Class[[B]]() {} $Class[[B]]::~$Class[[B]]() {} - $Primitive[[void]] $Function[[f]] () { + $Primitive[[void]] $FunctionDeclaration[[f]] () { $Class[[B]] $LocalVariable[[BB]] = $Class[[B]](); $LocalVariable[[BB]].~$Class[[B]](); $Class[[B]](); @@ -203,8 +206,8 @@ $Primitive[[double]] $Field[[B]]; $Class[[D]] $Field[[E]]; static $Primitive[[double]] $StaticField[[S]]; - static $Primitive[[void]] $StaticMethod[[bar]]() {} - $Primitive[[void]] $Method[[foo]]() { + static $Primitive[[void]] $StaticMethodDeclaration[[bar]]() {} + $Primitive[[void]] $MethodDeclaration[[foo]]() { $Field[[B]] = 123; this->$Field[[B]] = 156; this->$Method[[foo]](); @@ -213,7 +216,7 @@ $StaticField[[S]] = 90.1; } }; - $Primitive[[void]] $Function[[foo]]() { + $Primitive[[void]] $FunctionDeclaration[[foo]]() { $Class[[A]] $LocalVariable[[AA]]; $LocalVariable[[AA]].$Field[[B]] += 2; $LocalVariable[[AA]].$Method[[foo]](); @@ -239,8 +242,8 @@ typedef $Enum[[E]] $Enum[[C]]; typedef $Enum[[C]] $Enum[[CC]]; using $Enum[[CD]] = $Enum[[CC]]; - $Enum[[CC]] $Function[[f]]($Class[[B]]); - $Enum[[CD]] $Function[[f]]($Class[[BB]]); + $Enum[[CC]] $FunctionDeclaration[[f]]($Class[[B]]); + $Enum[[CD]] $FunctionDeclaration[[f]]($Class[[BB]]); typedef $Namespace[[a]]::$Primitive[[C]] $Primitive[[PC]]; typedef $Primitive[[float]] $Primitive[[F]]; )cpp", @@ -248,7 +251,7 @@ template class $Class[[A]] { $TemplateParameter[[T]] $Field[[AA]]; - $TemplateParameter[[T]] $Method[[foo]](); + $TemplateParameter[[T]] $MethodDeclaration[[foo]](); }; template class $Class[[B]] { @@ -262,13 +265,13 @@ class $Class[[BB]]<$TemplateParameter[[T]], $TemplateParameter[[T]]*> {}; template class $TemplateParameter[[T]], class $TemplateParameter[[C]]> - $TemplateParameter[[T]]<$TemplateParameter[[C]]> $Function[[f]](); + $TemplateParameter[[T]]<$TemplateParameter[[C]]> $FunctionDeclaration[[f]](); template class $Class[[Foo]] {}; template - $Primitive[[void]] $Function[[foo]]($TemplateParameter[[T]] ...); + $Primitive[[void]] $FunctionDeclaration[[foo]]($TemplateParameter[[T]] ...); )cpp", R"cpp( template @@ -286,7 +289,7 @@ explicit operator $Primitive[[int]]() const; operator $Class[[Foo]](); }; - $Primitive[[void]] $Function[[f]]() { + $Primitive[[void]] $FunctionDeclaration[[f]]() { $Class[[Bar]] $LocalVariable[[B]]; $Class[[Foo]] $LocalVariable[[F]] = $LocalVariable[[B]]; $Class[[Foo]] *$LocalVariable[[FP]] = ($Class[[Foo]]*)$LocalVariable[[B]]; @@ -342,20 +345,20 @@ class $Class[[GR]] {}; template<$Primitive[[int]] *$TemplateParameter[[U]]> class $Class[[IP]] { - $Primitive[[void]] $Method[[f]]() { + $Primitive[[void]] $MethodDeclaration[[f]]() { *$TemplateParameter[[U]] += 5; } }; template<$Primitive[[unsigned]] $TemplateParameter[[U]] = 2> class $Class[[Foo]] { - $Primitive[[void]] $Method[[f]]() { + $Primitive[[void]] $MethodDeclaration[[f]]() { for($Primitive[[int]] $LocalVariable[[I]] = 0; $LocalVariable[[I]] < $TemplateParameter[[U]];) {} } }; $Class[[G]] $Variable[[L]]; - $Primitive[[void]] $Function[[f]]() { + $Primitive[[void]] $FunctionDeclaration[[f]]() { $Class[[Foo]]<123> $LocalVariable[[F]]; $Class[[GP]]<&$Variable[[L]]> $LocalVariable[[LL]]; $Class[[GR]]<$Variable[[L]]> $LocalVariable[[LLL]]; @@ -365,22 +368,22 @@ template struct $Class[[G]] { - $Primitive[[void]] $Method[[foo]]( + $Primitive[[void]] $MethodDeclaration[[foo]]( $TemplateParameter[[T]] *$Parameter[[O]]) { ($Parameter[[O]]->*$TemplateParameter[[method]])(10); } }; struct $Class[[F]] { - $Primitive[[void]] $Method[[f]]($Primitive[[int]]); + $Primitive[[void]] $MethodDeclaration[[f]]($Primitive[[int]]); }; template<$Primitive[[void]] (*$TemplateParameter[[Func]])()> struct $Class[[A]] { - $Primitive[[void]] $Method[[f]]() { + $Primitive[[void]] $MethodDeclaration[[f]]() { (*$TemplateParameter[[Func]])(); } }; - $Primitive[[void]] $Function[[foo]]() { + $Primitive[[void]] $FunctionDeclaration[[foo]]() { $Class[[F]] $LocalVariable[[FF]]; $Class[[G]]<$Class[[F]], &$Class[[F]]::$Method[[f]]> $LocalVariable[[GG]]; $LocalVariable[[GG]].$Method[[foo]](&$LocalVariable[[FF]]); @@ -403,7 +406,7 @@ #define SOME_NAME variable #define SOME_NAME_SET variable2 = 123 #define INC_VAR(X) X += 2 - $Primitive[[void]] $Function[[foo]]() { + $Primitive[[void]] $FunctionDeclaration[[foo]]() { DEF_VAR($LocalVariable[[X]], 123); DEF_VAR_REV(908, $LocalVariable[[XY]]); $Primitive[[int]] CPY( $LocalVariable[[XX]] ); @@ -422,7 +425,7 @@ #define CALL_FN(F) F(); #define DEF_FN(F) void F () - DEF_FN($Function[[g]]) { + DEF_FN($FunctionDeclaration[[g]]) { CALL_FN($Function[[foo]]); } )cpp", @@ -431,8 +434,8 @@ #define assert(COND) if (!(COND)) { fail("assertion failed" #COND); } $Primitive[[int]] $Variable[[x]]; $Primitive[[int]] $Variable[[y]]; - $Primitive[[int]] $Function[[f]](); - $Primitive[[void]] $Function[[foo]]() { + $Primitive[[int]] $FunctionDeclaration[[f]](); + $Primitive[[void]] $FunctionDeclaration[[foo]]() { assert($Variable[[x]] != $Variable[[y]]); assert($Variable[[x]] != $Function[[f]]()); } diff --git a/clang-tools-extra/clangd/unittests/TweakTests.cpp b/clang-tools-extra/clangd/unittests/TweakTests.cpp --- a/clang-tools-extra/clangd/unittests/TweakTests.cpp +++ b/clang-tools-extra/clangd/unittests/TweakTests.cpp @@ -37,7 +37,8 @@ EXPECT_EQ(apply("^if (true) {return 100;} else {continue;}"), "if (true) {continue;} else {return 100;}"); EXPECT_EQ(apply("^if () {return 100;} else {continue;}"), - "if () {continue;} else {return 100;}") << "broken condition"; + "if () {continue;} else {return 100;}") + << "broken condition"; EXPECT_AVAILABLE("^i^f^^(^t^r^u^e^) { return 100; } ^e^l^s^e^ { continue; }"); EXPECT_UNAVAILABLE("if (true) {^return ^100;^ } else { ^continue^;^ }"); // Available in subexpressions of the condition; @@ -68,7 +69,7 @@ EXPECT_UNAVAILABLE(R"cpp(R"(multi )" ^"token " u8"str\ning")cpp"); // nonascii EXPECT_UNAVAILABLE(R"cpp(^R^"^(^multi )" "token " "str\ning")cpp"); // raw EXPECT_UNAVAILABLE(R"cpp(^"token\n" __FILE__)cpp"); // chunk is macro - EXPECT_UNAVAILABLE(R"cpp(^"a\r\n";)cpp"); // forbidden escape char + EXPECT_UNAVAILABLE(R"cpp(^"a\r\n";)cpp"); // forbidden escape char const char *Input = R"cpp(R"(multi token)" "\nst^ring\n" "literal")cpp"; @@ -254,11 +255,11 @@ void f(int a) { int y = PLUS([[1+a]]); })cpp", - /*FIXME: It should be extracted like this. - R"cpp(#define PLUS(x) x++ - void f(int a) { - auto dummy = 1+a; int y = PLUS(dummy); - })cpp"},*/ + /*FIXME: It should be extracted like this. + R"cpp(#define PLUS(x) x++ + void f(int a) { + auto dummy = 1+a; int y = PLUS(dummy); + })cpp"},*/ R"cpp(#define PLUS(x) x++ void f(int a) { auto dummy = PLUS(1+a); int y = dummy; @@ -269,13 +270,13 @@ if(1) LOOP(5 + [[3]]) })cpp", - /*FIXME: It should be extracted like this. SelectionTree needs to be - * fixed for macros. - R"cpp(#define LOOP(x) while (1) {a = x;} - void f(int a) { - auto dummy = 3; if(1) - LOOP(5 + dummy) - })cpp"},*/ + /*FIXME: It should be extracted like this. SelectionTree needs to be + * fixed for macros. + R"cpp(#define LOOP(x) while (1) {a = x;} + void f(int a) { + auto dummy = 3; if(1) + LOOP(5 + dummy) + })cpp"},*/ R"cpp(#define LOOP(x) while (1) {a = x;} void f(int a) { auto dummy = LOOP(5 + 3); if(1) @@ -371,8 +372,8 @@ void f() { auto dummy = S(2) + S(3) + S(4); S x = S(1) + dummy + S(5); })cpp"}, - // Don't try to analyze across macro boundaries - // FIXME: it'd be nice to do this someday (in a safe way) + // Don't try to analyze across macro boundaries + // FIXME: it'd be nice to do this someday (in a safe way) {R"cpp(#define ECHO(X) X void f() { int x = 1 + [[ECHO(2 + 3) + 4]] + 5; @@ -400,19 +401,19 @@ EXPECT_AVAILABLE("^vo^id^ ^f(^) {^}^"); // available everywhere. EXPECT_AVAILABLE("[[int a; int b;]]"); EXPECT_EQ("/* storage.type.primitive.cpp */void " - "/* entity.name.function.cpp */f() {}", + "/* entity.name.function.declaration.cpp */f() {}", apply("void ^f() {}")); EXPECT_EQ(apply("[[void f1(); void f2();]]"), "/* storage.type.primitive.cpp */void " - "/* entity.name.function.cpp */f1(); " + "/* entity.name.function.declaration.cpp */f1(); " "/* storage.type.primitive.cpp */void " - "/* entity.name.function.cpp */f2();"); + "/* entity.name.function.declaration.cpp */f2();"); EXPECT_EQ(apply("void f1(); void f2() {^}"), "void f1(); " "/* storage.type.primitive.cpp */void " - "/* entity.name.function.cpp */f2() {}"); + "/* entity.name.function.declaration.cpp */f2() {}"); } TWEAK_TEST(ExpandMacro); @@ -489,7 +490,7 @@ StartsWith("fail: Could not expand type of lambda expression")); // inline namespaces EXPECT_EQ(apply("au^to x = inl_ns::Visible();"), - "Visible x = inl_ns::Visible();"); + "Visible x = inl_ns::Visible();"); // local class EXPECT_EQ(apply("namespace x { void y() { struct S{}; ^auto z = S(); } }"), "namespace x { void y() { struct S{}; S z = S(); } }");