[clangd] Respect ArgumentLists for struct templates (#212094)
Also fix a bug in index::getSymbolKind where the returned symbol kind would be Class for a struct template. Fixes https://github.com/clangd/clangd/issues/2684
This commit is contained in:
parent
e4205abdad
commit
e9240abc52
5 changed files with 40 additions and 7 deletions
|
|
@ -643,6 +643,7 @@ private:
|
|||
// 'CompletionItemKind::Interface' matches template type aliases.
|
||||
if (Completion.Kind == CompletionItemKind::Interface ||
|
||||
Completion.Kind == CompletionItemKind::Class ||
|
||||
Completion.Kind == CompletionItemKind::Struct ||
|
||||
Completion.Kind == CompletionItemKind::Variable) {
|
||||
if (Snippet->front() != '<')
|
||||
return *Snippet; // Not an arg snippet?
|
||||
|
|
|
|||
|
|
@ -841,7 +841,7 @@ TEST(CompletionTest, Kinds) {
|
|||
EXPECT_THAT(
|
||||
Results.Completions,
|
||||
UnorderedElementsAre(
|
||||
AllOf(named("complete_class"), kind(CompletionItemKind::Class)),
|
||||
AllOf(named("complete_class"), kind(CompletionItemKind::Struct)),
|
||||
AllOf(named("complete_function"), kind(CompletionItemKind::Function)),
|
||||
AllOf(named("complete_type_alias"),
|
||||
kind(CompletionItemKind::Interface)),
|
||||
|
|
@ -2996,6 +2996,8 @@ TEST(CompletionTest, ArgumentListsPolicy) {
|
|||
template <class T>
|
||||
class foo_class{};
|
||||
template <class T>
|
||||
struct foo_struct{};
|
||||
template <class T>
|
||||
using foo_alias = T**;
|
||||
template <class T>
|
||||
T foo_var = T{};
|
||||
|
|
@ -3004,9 +3006,35 @@ TEST(CompletionTest, ArgumentListsPolicy) {
|
|||
EXPECT_THAT(
|
||||
Results.Completions,
|
||||
UnorderedElementsAre(AllOf(named("foo_class"), snippetSuffix("<$0>")),
|
||||
AllOf(named("foo_struct"), snippetSuffix("<$0>")),
|
||||
AllOf(named("foo_alias"), snippetSuffix("<$0>")),
|
||||
AllOf(named("foo_var"), snippetSuffix("<$0>"))));
|
||||
}
|
||||
{
|
||||
const char *Header = R"cpp(
|
||||
template <class T>
|
||||
class foo_class{};
|
||||
template <class T>
|
||||
struct foo_struct{};
|
||||
template <class T>
|
||||
using foo_alias = T**;
|
||||
template <class T>
|
||||
T foo_var = T{};
|
||||
)cpp";
|
||||
auto Index = TestTU::withHeaderCode(Header).index();
|
||||
Opts.Index = Index.get();
|
||||
auto Results = completions(
|
||||
R"cpp(
|
||||
void f() { foo_^ })cpp",
|
||||
{}, Opts);
|
||||
EXPECT_THAT(
|
||||
Results.Completions,
|
||||
UnorderedElementsAre(AllOf(named("foo_class"), snippetSuffix("<$0>")),
|
||||
AllOf(named("foo_struct"), snippetSuffix("<$0>")),
|
||||
AllOf(named("foo_alias"), snippetSuffix("<$0>")),
|
||||
AllOf(named("foo_var"), snippetSuffix("<$0>"))));
|
||||
Opts.Index = nullptr;
|
||||
}
|
||||
{
|
||||
auto Results = completions(
|
||||
R"cpp(
|
||||
|
|
|
|||
|
|
@ -302,11 +302,15 @@ SymbolInfo index::getSymbolInfo(const Decl *D) {
|
|||
Info.Lang = SymbolLanguage::CXX;
|
||||
break;
|
||||
}
|
||||
case Decl::ClassTemplate:
|
||||
Info.Kind = SymbolKind::Class;
|
||||
case Decl::ClassTemplate: {
|
||||
const ClassTemplateDecl *CTD = cast<ClassTemplateDecl>(D);
|
||||
Info.Kind = CTD->getTemplatedDecl()->getTagKind() == TagTypeKind::Struct
|
||||
? SymbolKind::Struct
|
||||
: SymbolKind::Class;
|
||||
Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
|
||||
Info.Lang = SymbolLanguage::CXX;
|
||||
break;
|
||||
}
|
||||
case Decl::FunctionTemplate:
|
||||
Info.Kind = SymbolKind::Function;
|
||||
Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ int ginitlist[] = {EnumVal};
|
|||
// CHECK-NEXT: [indexEntityReference]: kind: namespace | name: NS | {{.*}} | loc: 44:7
|
||||
// CHECK-NEXT: [indexEntityReference]: kind: typedef | name: Foo | {{.*}} | loc: 44:11
|
||||
|
||||
// CHECK: [indexDeclaration]: kind: c++-class-template | name: TS | {{.*}} | loc: 47:8
|
||||
// CHECK: [indexDeclaration]: kind: struct-template | name: TS | {{.*}} | loc: 47:8
|
||||
// CHECK-NEXT: [indexDeclaration]: kind: struct-template-partial-spec | name: TS | USR: c:@SP>1#T@TS>#t0.0#I | {{.*}} | loc: 50:8
|
||||
// CHECK-NEXT: [indexDeclaration]: kind: typedef | name: MyInt | USR: c:index-refs.cpp@SP>1#T@TS>#t0.0#I@T@MyInt | {{.*}} | loc: 51:15 | semantic-container: [TS:50:8] | lexical-container: [TS:50:8]
|
||||
/* when indexing implicit instantiations
|
||||
|
|
|
|||
|
|
@ -24,6 +24,6 @@ struct D : B<T> {};
|
|||
// CHECK-NEXT: [indexEntityReference]: kind: c++-class-template | name: Foo | USR: c:@ST>1#T@Foo
|
||||
// CHECK-NEXT: [indexEntityReference]: kind: c++-instance-method | name: f | USR: c:@ST>1#T@Foo@F@f#t0.0#
|
||||
|
||||
// CHECK: [indexDeclaration]: kind: c++-class-template | name: D
|
||||
// CHECK-NEXT: <base>: kind: c++-class-template | name: B
|
||||
// CHECK-NEXT: [indexEntityReference]: kind: c++-class-template | name: B
|
||||
// CHECK: [indexDeclaration]: kind: struct-template | name: D
|
||||
// CHECK-NEXT: <base>: kind: struct-template | name: B
|
||||
// CHECK-NEXT: [indexEntityReference]: kind: struct-template | name: B
|
||||
|
|
|
|||
Loading…
Reference in a new issue