mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-18 19:16:43 +00:00
[clangd] Add decl/def support to SymbolDetails
Add an optional declarationRange and definitionRange to SymbolDetails. This will allow SourceKit-LSP to implement toggling between goto definition/declaration based on whether the symbol at the cursor is a definition or declaration. Differential Revision: https://reviews.llvm.org/D130041
This commit is contained in:
parent
2d9eae4152
commit
61ef0ab701
@ -14,6 +14,7 @@
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclBase.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "clang/AST/DeclarationName.h"
|
||||
#include "clang/AST/ExprCXX.h"
|
||||
|
@ -734,7 +734,9 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &O,
|
||||
|
||||
bool operator==(const SymbolDetails &LHS, const SymbolDetails &RHS) {
|
||||
return LHS.name == RHS.name && LHS.containerName == RHS.containerName &&
|
||||
LHS.USR == RHS.USR && LHS.ID == RHS.ID;
|
||||
LHS.USR == RHS.USR && LHS.ID == RHS.ID &&
|
||||
LHS.declarationRange == RHS.declarationRange &&
|
||||
LHS.definitionRange == RHS.definitionRange;
|
||||
}
|
||||
|
||||
llvm::json::Value toJSON(const SymbolDetails &P) {
|
||||
@ -755,6 +757,12 @@ llvm::json::Value toJSON(const SymbolDetails &P) {
|
||||
if (P.ID)
|
||||
Result["id"] = P.ID.str();
|
||||
|
||||
if (P.declarationRange)
|
||||
Result["declarationRange"] = *P.declarationRange;
|
||||
|
||||
if (P.definitionRange)
|
||||
Result["definitionRange"] = *P.definitionRange;
|
||||
|
||||
// FIXME: workaround for older gcc/clang
|
||||
return std::move(Result);
|
||||
}
|
||||
|
@ -1093,6 +1093,10 @@ struct SymbolDetails {
|
||||
std::string USR;
|
||||
|
||||
SymbolID ID;
|
||||
|
||||
llvm::Optional<Location> declarationRange;
|
||||
|
||||
llvm::Optional<Location> definitionRange;
|
||||
};
|
||||
llvm::json::Value toJSON(const SymbolDetails &);
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolDetails &);
|
||||
|
@ -1481,7 +1481,7 @@ std::vector<SymbolDetails> getSymbolInfo(ParsedAST &AST, Position Pos) {
|
||||
llvm::consumeError(CurLoc.takeError());
|
||||
return {};
|
||||
}
|
||||
|
||||
auto MainFilePath = AST.tuPath();
|
||||
std::vector<SymbolDetails> Results;
|
||||
|
||||
// We also want the targets of using-decls, so we include
|
||||
@ -1489,6 +1489,8 @@ std::vector<SymbolDetails> getSymbolInfo(ParsedAST &AST, Position Pos) {
|
||||
DeclRelationSet Relations = DeclRelation::TemplatePattern |
|
||||
DeclRelation::Alias | DeclRelation::Underlying;
|
||||
for (const NamedDecl *D : getDeclAtPosition(AST, *CurLoc, Relations)) {
|
||||
D = getPreferredDecl(D);
|
||||
|
||||
SymbolDetails NewSymbol;
|
||||
std::string QName = printQualifiedName(*D);
|
||||
auto SplitQName = splitQualifiedName(QName);
|
||||
@ -1505,6 +1507,12 @@ std::vector<SymbolDetails> getSymbolInfo(ParsedAST &AST, Position Pos) {
|
||||
NewSymbol.USR = std::string(USR.str());
|
||||
NewSymbol.ID = SymbolID(NewSymbol.USR);
|
||||
}
|
||||
if (const NamedDecl *Def = getDefinition(D))
|
||||
NewSymbol.definitionRange = makeLocation(
|
||||
AST.getASTContext(), nameLocation(*Def, SM), MainFilePath);
|
||||
NewSymbol.declarationRange =
|
||||
makeLocation(AST.getASTContext(), nameLocation(*D, SM), MainFilePath);
|
||||
|
||||
Results.push_back(std::move(NewSymbol));
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,36 @@
|
||||
# RUN: clangd -lit-test < %s | FileCheck %s
|
||||
{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
|
||||
---
|
||||
{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///simple.cpp","languageId":"cpp","version":1,"text":"void foo(); int main() { foo(); }\n"}}}
|
||||
{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///simple.cpp","languageId":"cpp","version":1,"text":"void foo(); void foo() {} int main() { foo(); }\n"}}}
|
||||
---
|
||||
{"jsonrpc":"2.0","id":1,"method":"textDocument/symbolInfo","params":{"textDocument":{"uri":"test:///simple.cpp"},"position":{"line":0,"character":27}}}
|
||||
{"jsonrpc":"2.0","id":1,"method":"textDocument/symbolInfo","params":{"textDocument":{"uri":"test:///simple.cpp"},"position":{"line":0,"character":40}}}
|
||||
# CHECK: "containerName": null,
|
||||
# CHECK-NEXT: "declarationRange": {
|
||||
# CHECK-NEXT: "range": {
|
||||
# CHECK-NEXT: "end": {
|
||||
# CHECK-NEXT: "character": 8,
|
||||
# CHECK-NEXT: "line": 0
|
||||
# CHECK-NEXT: },
|
||||
# CHECK-NEXT: "start": {
|
||||
# CHECK-NEXT: "character": 5,
|
||||
# CHECK-NEXT: "line": 0
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: },
|
||||
# CHECK-NEXT: "uri": "file://{{.*}}/clangd-test/simple.cpp"
|
||||
# CHECK-NEXT: },
|
||||
# CHECK-NEXT: "definitionRange": {
|
||||
# CHECK-NEXT: "range": {
|
||||
# CHECK-NEXT: "end": {
|
||||
# CHECK-NEXT: "character": 20,
|
||||
# CHECK-NEXT: "line": 0
|
||||
# CHECK-NEXT: },
|
||||
# CHECK-NEXT: "start": {
|
||||
# CHECK-NEXT: "character": 17,
|
||||
# CHECK-NEXT: "line": 0
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: },
|
||||
# CHECK-NEXT: "uri": "file://{{.*}}/clangd-test/simple.cpp"
|
||||
# CHECK-NEXT: },
|
||||
# CHECK-NEXT: "id": "CA2EBE44A1D76D2A",
|
||||
# CHECK-NEXT: "name": "foo",
|
||||
# CHECK-NEXT: "usr": "c:@F@foo#"
|
||||
|
@ -18,45 +18,79 @@ namespace {
|
||||
|
||||
using ::testing::UnorderedElementsAreArray;
|
||||
|
||||
auto CreateExpectedSymbolDetails = [](const std::string &Name,
|
||||
const std::string &Container,
|
||||
const std::string &USR) {
|
||||
return SymbolDetails{Name, Container, USR, SymbolID(USR)};
|
||||
// Partial SymbolDetails with the rest filled in at testing time.
|
||||
struct ExpectedSymbolDetails {
|
||||
std::string Name;
|
||||
std::string Container;
|
||||
std::string USR;
|
||||
const char *DeclMarker = nullptr;
|
||||
const char *DefMarker = nullptr;
|
||||
};
|
||||
|
||||
TEST(SymbolInfoTests, All) {
|
||||
std::pair<const char *, std::vector<SymbolDetails>>
|
||||
std::pair<const char *, std::vector<ExpectedSymbolDetails>>
|
||||
TestInputExpectedOutput[] = {
|
||||
{
|
||||
R"cpp( // Simple function reference - declaration
|
||||
void foo();
|
||||
void $decl[[foo]]();
|
||||
int bar() {
|
||||
fo^o();
|
||||
}
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("foo", "", "c:@F@foo#")}},
|
||||
{ExpectedSymbolDetails{"foo", "", "c:@F@foo#", "decl"}}},
|
||||
{
|
||||
R"cpp( // Simple function reference - definition
|
||||
void foo() {}
|
||||
void $def[[foo]]() {}
|
||||
int bar() {
|
||||
fo^o();
|
||||
}
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("foo", "", "c:@F@foo#")}},
|
||||
{ExpectedSymbolDetails{"foo", "", "c:@F@foo#", "def", "def"}}},
|
||||
{
|
||||
R"cpp( // Simple function reference - decl and def
|
||||
void $decl[[foo]]();
|
||||
void $def[[foo]]() {}
|
||||
int bar() {
|
||||
fo^o();
|
||||
}
|
||||
)cpp",
|
||||
{ExpectedSymbolDetails{"foo", "", "c:@F@foo#", "decl", "def"}}},
|
||||
{
|
||||
R"cpp( // Simple class reference - decl and def
|
||||
@interface $decl[[Foo]]
|
||||
@end
|
||||
@implementation $def[[Foo]]
|
||||
@end
|
||||
void doSomething(F^oo *obj) {}
|
||||
)cpp",
|
||||
{ExpectedSymbolDetails{"Foo", "", "c:objc(cs)Foo", "decl",
|
||||
"def"}}},
|
||||
{
|
||||
R"cpp( // Simple method reference - decl and def
|
||||
@interface Foo
|
||||
- (void)$decl[[foo]];
|
||||
@end
|
||||
@implementation Foo
|
||||
- (void)$def[[fo^o]] {}
|
||||
@end
|
||||
)cpp",
|
||||
{ExpectedSymbolDetails{"foo", "Foo::", "c:objc(cs)Foo(im)foo",
|
||||
"decl", "def"}}},
|
||||
{
|
||||
R"cpp( // Function in namespace reference
|
||||
namespace bar {
|
||||
void foo();
|
||||
void $decl[[foo]]();
|
||||
int baz() {
|
||||
fo^o();
|
||||
}
|
||||
}
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("foo", "bar::", "c:@N@bar@F@foo#")}},
|
||||
{ExpectedSymbolDetails{"foo", "bar::", "c:@N@bar@F@foo#",
|
||||
"decl"}}},
|
||||
{
|
||||
R"cpp( // Function in different namespace reference
|
||||
namespace bar {
|
||||
void foo();
|
||||
void $decl[[foo]]();
|
||||
}
|
||||
namespace barbar {
|
||||
int baz() {
|
||||
@ -64,10 +98,11 @@ TEST(SymbolInfoTests, All) {
|
||||
}
|
||||
}
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("foo", "bar::", "c:@N@bar@F@foo#")}},
|
||||
{ExpectedSymbolDetails{"foo", "bar::", "c:@N@bar@F@foo#",
|
||||
"decl"}}},
|
||||
{
|
||||
R"cpp( // Function in global namespace reference
|
||||
void foo();
|
||||
void $decl[[foo]]();
|
||||
namespace Nbar {
|
||||
namespace Nbaz {
|
||||
int baz() {
|
||||
@ -76,11 +111,11 @@ TEST(SymbolInfoTests, All) {
|
||||
}
|
||||
}
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("foo", "", "c:@F@foo#")}},
|
||||
{ExpectedSymbolDetails{"foo", "", "c:@F@foo#", "decl"}}},
|
||||
{
|
||||
R"cpp( // Function in anonymous namespace reference
|
||||
namespace {
|
||||
void foo();
|
||||
void $decl[[foo]]();
|
||||
}
|
||||
namespace barbar {
|
||||
int baz() {
|
||||
@ -88,13 +123,13 @@ TEST(SymbolInfoTests, All) {
|
||||
}
|
||||
}
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("foo", "(anonymous)",
|
||||
"c:TestTU.cpp@aN@F@foo#")}},
|
||||
{ExpectedSymbolDetails{"foo", "(anonymous)",
|
||||
"c:TestTU.cpp@aN@F@foo#", "decl"}}},
|
||||
{
|
||||
R"cpp( // Function reference - ADL
|
||||
namespace bar {
|
||||
struct BarType {};
|
||||
void foo(const BarType&);
|
||||
void $decl[[foo]](const BarType&);
|
||||
}
|
||||
namespace barbar {
|
||||
int baz() {
|
||||
@ -103,67 +138,71 @@ TEST(SymbolInfoTests, All) {
|
||||
}
|
||||
}
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails(
|
||||
"foo", "bar::", "c:@N@bar@F@foo#&1$@N@bar@S@BarType#")}},
|
||||
{ExpectedSymbolDetails{
|
||||
"foo", "bar::", "c:@N@bar@F@foo#&1$@N@bar@S@BarType#",
|
||||
"decl"}}},
|
||||
{
|
||||
R"cpp( // Global value reference
|
||||
int value;
|
||||
int $def[[value]];
|
||||
void foo(int) { }
|
||||
void bar() {
|
||||
foo(val^ue);
|
||||
}
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("value", "", "c:@value")}},
|
||||
{ExpectedSymbolDetails{"value", "", "c:@value", "def", "def"}}},
|
||||
{
|
||||
R"cpp( // Local value reference
|
||||
void foo() { int aaa; int bbb = aa^a; }
|
||||
void foo() { int $def[[aaa]]; int bbb = aa^a; }
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("aaa", "foo",
|
||||
"c:TestTU.cpp@49@F@foo#@aaa")}},
|
||||
{ExpectedSymbolDetails{"aaa", "foo", "c:TestTU.cpp@49@F@foo#@aaa",
|
||||
"def", "def"}}},
|
||||
{
|
||||
R"cpp( // Function param
|
||||
void bar(int aaa) {
|
||||
void bar(int $def[[aaa]]) {
|
||||
int bbb = a^aa;
|
||||
}
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("aaa", "bar",
|
||||
"c:TestTU.cpp@38@F@bar#I#@aaa")}},
|
||||
{ExpectedSymbolDetails{
|
||||
"aaa", "bar", "c:TestTU.cpp@38@F@bar#I#@aaa", "def", "def"}}},
|
||||
{
|
||||
R"cpp( // Lambda capture
|
||||
void foo() {
|
||||
int ii;
|
||||
int $def[[ii]];
|
||||
auto lam = [ii]() {
|
||||
return i^i;
|
||||
};
|
||||
}
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("ii", "foo",
|
||||
"c:TestTU.cpp@54@F@foo#@ii")}},
|
||||
{ExpectedSymbolDetails{"ii", "foo", "c:TestTU.cpp@54@F@foo#@ii",
|
||||
"def", "def"}}},
|
||||
{
|
||||
R"cpp( // Macro reference
|
||||
#define MACRO 5\nint i = MAC^RO;
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("MACRO", "",
|
||||
"c:TestTU.cpp@38@macro@MACRO")}},
|
||||
{ExpectedSymbolDetails{"MACRO", "",
|
||||
"c:TestTU.cpp@38@macro@MACRO"}}},
|
||||
{
|
||||
R"cpp( // Macro reference
|
||||
#define MACRO 5\nint i = MACRO^;
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("MACRO", "",
|
||||
"c:TestTU.cpp@38@macro@MACRO")}},
|
||||
{ExpectedSymbolDetails{"MACRO", "",
|
||||
"c:TestTU.cpp@38@macro@MACRO"}}},
|
||||
{
|
||||
R"cpp( // Multiple symbols returned - using overloaded function name
|
||||
void foo() {}
|
||||
void foo(bool) {}
|
||||
void foo(int) {}
|
||||
void $def[[foo]]() {}
|
||||
void $def_bool[[foo]](bool) {}
|
||||
void $def_int[[foo]](int) {}
|
||||
namespace bar {
|
||||
using ::fo^o;
|
||||
using ::$decl[[fo^o]];
|
||||
}
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("foo", "", "c:@F@foo#"),
|
||||
CreateExpectedSymbolDetails("foo", "", "c:@F@foo#b#"),
|
||||
CreateExpectedSymbolDetails("foo", "", "c:@F@foo#I#"),
|
||||
CreateExpectedSymbolDetails("foo", "bar::", "c:@N@bar@UD@foo")}},
|
||||
{ExpectedSymbolDetails{"foo", "", "c:@F@foo#", "def", "def"},
|
||||
ExpectedSymbolDetails{"foo", "", "c:@F@foo#b#", "def_bool",
|
||||
"def_bool"},
|
||||
ExpectedSymbolDetails{"foo", "", "c:@F@foo#I#", "def_int",
|
||||
"def_int"},
|
||||
ExpectedSymbolDetails{"foo", "bar::", "c:@N@bar@UD@foo",
|
||||
"decl"}}},
|
||||
{
|
||||
R"cpp( // Multiple symbols returned - implicit conversion
|
||||
struct foo {};
|
||||
@ -172,133 +211,142 @@ TEST(SymbolInfoTests, All) {
|
||||
};
|
||||
void func_baz1(bar) {}
|
||||
void func_baz2() {
|
||||
foo ff;
|
||||
foo $def[[ff]];
|
||||
func_baz1(f^f);
|
||||
}
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails(
|
||||
"ff", "func_baz2", "c:TestTU.cpp@218@F@func_baz2#@ff")}},
|
||||
{ExpectedSymbolDetails{"ff", "func_baz2",
|
||||
"c:TestTU.cpp@218@F@func_baz2#@ff", "def",
|
||||
"def"}}},
|
||||
{
|
||||
R"cpp( // Type reference - declaration
|
||||
struct foo;
|
||||
struct $decl[[foo]];
|
||||
void bar(fo^o*);
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("foo", "", "c:@S@foo")}},
|
||||
{ExpectedSymbolDetails{"foo", "", "c:@S@foo", "decl"}}},
|
||||
{
|
||||
R"cpp( // Type reference - definition
|
||||
struct foo {};
|
||||
struct $def[[foo]] {};
|
||||
void bar(fo^o*);
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("foo", "", "c:@S@foo")}},
|
||||
{ExpectedSymbolDetails{"foo", "", "c:@S@foo", "def", "def"}}},
|
||||
{
|
||||
R"cpp( // Type Reference - template argument
|
||||
struct foo {};
|
||||
struct $def[[foo]] {};
|
||||
template<class T> struct bar {};
|
||||
void baz() {
|
||||
bar<fo^o> b;
|
||||
}
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("foo", "", "c:@S@foo")}},
|
||||
{ExpectedSymbolDetails{"foo", "", "c:@S@foo", "def", "def"}}},
|
||||
{
|
||||
R"cpp( // Template parameter reference - type param
|
||||
template<class TT> struct bar {
|
||||
template<class $def[[TT]]> struct bar {
|
||||
T^T t;
|
||||
};
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("TT", "bar::", "c:TestTU.cpp@65")}},
|
||||
{ExpectedSymbolDetails{"TT", "bar::", "c:TestTU.cpp@65", "def",
|
||||
"def"}}},
|
||||
{
|
||||
R"cpp( // Template parameter reference - type param
|
||||
template<int NN> struct bar {
|
||||
template<int $def[[NN]]> struct bar {
|
||||
int a = N^N;
|
||||
};
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("NN", "bar::", "c:TestTU.cpp@65")}},
|
||||
{ExpectedSymbolDetails{"NN", "bar::", "c:TestTU.cpp@65", "def",
|
||||
"def"}}},
|
||||
{
|
||||
R"cpp( // Class member reference - objec
|
||||
struct foo {
|
||||
int aa;
|
||||
int $def[[aa]];
|
||||
};
|
||||
void bar() {
|
||||
foo f;
|
||||
f.a^a;
|
||||
}
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("aa", "foo::", "c:@S@foo@FI@aa")}},
|
||||
{ExpectedSymbolDetails{"aa", "foo::", "c:@S@foo@FI@aa", "def",
|
||||
"def"}}},
|
||||
{
|
||||
R"cpp( // Class member reference - pointer
|
||||
struct foo {
|
||||
int aa;
|
||||
int $def[[aa]];
|
||||
};
|
||||
void bar() {
|
||||
&foo::a^a;
|
||||
}
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("aa", "foo::", "c:@S@foo@FI@aa")}},
|
||||
{ExpectedSymbolDetails{"aa", "foo::", "c:@S@foo@FI@aa", "def",
|
||||
"def"}}},
|
||||
{
|
||||
R"cpp( // Class method reference - objec
|
||||
struct foo {
|
||||
void aa() {}
|
||||
void $def[[aa]]() {}
|
||||
};
|
||||
void bar() {
|
||||
foo f;
|
||||
f.a^a();
|
||||
}
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("aa", "foo::", "c:@S@foo@F@aa#")}},
|
||||
{ExpectedSymbolDetails{"aa", "foo::", "c:@S@foo@F@aa#", "def",
|
||||
"def"}}},
|
||||
{
|
||||
R"cpp( // Class method reference - pointer
|
||||
struct foo {
|
||||
void aa() {}
|
||||
void $def[[aa]]() {}
|
||||
};
|
||||
void bar() {
|
||||
&foo::a^a;
|
||||
}
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("aa", "foo::", "c:@S@foo@F@aa#")}},
|
||||
{ExpectedSymbolDetails{"aa", "foo::", "c:@S@foo@F@aa#", "def",
|
||||
"def"}}},
|
||||
{
|
||||
R"cpp( // Typedef
|
||||
typedef int foo;
|
||||
typedef int $decl[[foo]];
|
||||
void bar() {
|
||||
fo^o a;
|
||||
}
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("foo", "", "c:TestTU.cpp@T@foo")}},
|
||||
{ExpectedSymbolDetails{"foo", "", "c:TestTU.cpp@T@foo", "decl"}}},
|
||||
{
|
||||
R"cpp( // Type alias
|
||||
using foo = int;
|
||||
using $decl[[foo]] = int;
|
||||
void bar() {
|
||||
fo^o a;
|
||||
}
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("foo", "", "c:@foo")}},
|
||||
{ExpectedSymbolDetails{"foo", "", "c:@foo", "decl"}}},
|
||||
{
|
||||
R"cpp( // Namespace reference
|
||||
namespace foo {}
|
||||
namespace $decl[[foo]] {}
|
||||
using namespace fo^o;
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("foo", "", "c:@N@foo")}},
|
||||
{ExpectedSymbolDetails{"foo", "", "c:@N@foo", "decl"}}},
|
||||
{
|
||||
R"cpp( // Enum value reference
|
||||
enum foo { bar, baz };
|
||||
enum foo { $def[[bar]], baz };
|
||||
void f() {
|
||||
foo fff = ba^r;
|
||||
}
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("bar", "foo", "c:@E@foo@bar")}},
|
||||
{ExpectedSymbolDetails{"bar", "foo", "c:@E@foo@bar", "def",
|
||||
"def"}}},
|
||||
{
|
||||
R"cpp( // Enum class value reference
|
||||
enum class foo { bar, baz };
|
||||
enum class foo { $def[[bar]], baz };
|
||||
void f() {
|
||||
foo fff = foo::ba^r;
|
||||
}
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("bar", "foo::", "c:@E@foo@bar")}},
|
||||
{ExpectedSymbolDetails{"bar", "foo::", "c:@E@foo@bar", "def",
|
||||
"def"}}},
|
||||
{
|
||||
R"cpp( // Parameters in declarations
|
||||
void foo(int ba^r);
|
||||
void foo(int $def[[ba^r]]);
|
||||
)cpp",
|
||||
{CreateExpectedSymbolDetails("bar", "foo",
|
||||
"c:TestTU.cpp@50@F@foo#I#@bar")}},
|
||||
{ExpectedSymbolDetails{
|
||||
"bar", "foo", "c:TestTU.cpp@50@F@foo#I#@bar", "def", "def"}}},
|
||||
{
|
||||
R"cpp( // Type inference with auto keyword
|
||||
struct foo {};
|
||||
@ -321,10 +369,26 @@ TEST(SymbolInfoTests, All) {
|
||||
|
||||
for (const auto &T : TestInputExpectedOutput) {
|
||||
Annotations TestInput(T.first);
|
||||
auto AST = TestTU::withCode(TestInput.code()).build();
|
||||
TestTU TU;
|
||||
TU.Code = std::string(TestInput.code());
|
||||
TU.ExtraArgs.push_back("-xobjective-c++");
|
||||
auto AST = TU.build();
|
||||
|
||||
std::vector<SymbolDetails> Expected;
|
||||
for (const auto &Sym : T.second) {
|
||||
llvm::Optional<Location> Decl, Def;
|
||||
if (Sym.DeclMarker)
|
||||
Decl = Location{URIForFile::canonicalize(testPath(TU.Filename), ""),
|
||||
TestInput.range(Sym.DeclMarker)};
|
||||
if (Sym.DefMarker)
|
||||
Def = Location{URIForFile::canonicalize(testPath(TU.Filename), ""),
|
||||
TestInput.range(Sym.DefMarker)};
|
||||
Expected.push_back(
|
||||
{Sym.Name, Sym.Container, Sym.USR, SymbolID(Sym.USR), Decl, Def});
|
||||
}
|
||||
|
||||
EXPECT_THAT(getSymbolInfo(AST, TestInput.point()),
|
||||
UnorderedElementsAreArray(T.second))
|
||||
UnorderedElementsAreArray(Expected))
|
||||
<< T.first;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user