Pos.end.character);
}
MATCHER_P(Refs, R, "") { return int(arg.References) == R; }
+MATCHER_P(ForCodeCompletion, IsIndexedForCodeCompletion, "") {
+ return arg.IsIndexedForCodeCompletion == IsIndexedForCodeCompletion;
+}
namespace clang {
namespace clangd {
CollectorOpts, PragmaHandler.get());
std::vector<std::string> Args = {
- "symbol_collector", "-fsyntax-only", "-xc++", "-std=c++11",
- "-include", TestHeaderName, TestFileName};
+ "symbol_collector", "-fsyntax-only", "-xc++",
+ "-std=c++11", "-include", TestHeaderName};
Args.insert(Args.end(), ExtraArgs.begin(), ExtraArgs.end());
+ // This allows to override the "-xc++" with something else, i.e.
+ // -xobjective-c++.
+ Args.push_back(TestFileName);
+
tooling::ToolInvocation Invocation(
Args,
Factory->create(), Files.get(),
TEST_F(SymbolCollectorTest, CollectSymbols) {
const std::string Header = R"(
class Foo {
+ Foo() {}
+ Foo(int a) {}
void f();
+ friend void f1();
+ friend class Friend;
+ Foo& operator=(const Foo&);
+ ~Foo();
+ class Nested {
+ void f();
+ };
};
+ class Friend {
+ };
+
void f1();
inline void f2() {}
static const int KInt = 2;
runSymbolCollector(Header, /*Main=*/"");
EXPECT_THAT(Symbols,
UnorderedElementsAreArray(
- {QName("Foo"), QName("f1"), QName("f2"), QName("KInt"),
- QName("kStr"), QName("foo"), QName("foo::bar"),
- QName("foo::int32"), QName("foo::int32_t"), QName("foo::v1"),
- QName("foo::bar::v2"), QName("foo::baz")}));
+ {AllOf(QName("Foo"), ForCodeCompletion(true)),
+ AllOf(QName("Foo::Foo"), ForCodeCompletion(false)),
+ AllOf(QName("Foo::Foo"), ForCodeCompletion(false)),
+ AllOf(QName("Foo::f"), ForCodeCompletion(false)),
+ AllOf(QName("Foo::~Foo"), ForCodeCompletion(false)),
+ AllOf(QName("Foo::operator="), ForCodeCompletion(false)),
+ AllOf(QName("Foo::Nested"), ForCodeCompletion(false)),
+ AllOf(QName("Foo::Nested::f"), ForCodeCompletion(false)),
+
+ AllOf(QName("Friend"), ForCodeCompletion(true)),
+ AllOf(QName("f1"), ForCodeCompletion(true)),
+ AllOf(QName("f2"), ForCodeCompletion(true)),
+ AllOf(QName("KInt"), ForCodeCompletion(true)),
+ AllOf(QName("kStr"), ForCodeCompletion(true)),
+ AllOf(QName("foo"), ForCodeCompletion(true)),
+ AllOf(QName("foo::bar"), ForCodeCompletion(true)),
+ AllOf(QName("foo::int32"), ForCodeCompletion(true)),
+ AllOf(QName("foo::int32_t"), ForCodeCompletion(true)),
+ AllOf(QName("foo::v1"), ForCodeCompletion(true)),
+ AllOf(QName("foo::bar::v2"), ForCodeCompletion(true)),
+ AllOf(QName("foo::baz"), ForCodeCompletion(true))}));
}
TEST_F(SymbolCollectorTest, Template) {
Annotations Header(R"(
// Template is indexed, specialization and instantiation is not.
- template <class T> struct [[Tmpl]] {T x = 0;};
+ template <class T> struct [[Tmpl]] {T $xdecl[[x]] = 0;};
template <> struct Tmpl<int> {};
extern template struct Tmpl<float>;
template struct Tmpl<double>;
)");
runSymbolCollector(Header.code(), /*Main=*/"");
- EXPECT_THAT(Symbols, UnorderedElementsAreArray({AllOf(
- QName("Tmpl"), DeclRange(Header.range()))}));
+ EXPECT_THAT(Symbols,
+ UnorderedElementsAreArray(
+ {AllOf(QName("Tmpl"), DeclRange(Header.range())),
+ AllOf(QName("Tmpl::x"), DeclRange(Header.range("xdecl")))}));
+}
+
+TEST_F(SymbolCollectorTest, ObjCSymbols) {
+ const std::string Header = R"(
+ @interface Person
+ - (void)someMethodName:(void*)name1 lastName:(void*)lName;
+ @end
+
+ @implementation Person
+ - (void)someMethodName:(void*)name1 lastName:(void*)lName{
+ int foo;
+ ^(int param){ int bar; };
+ }
+ @end
+
+ @interface Person (MyCategory)
+ - (void)someMethodName2:(void*)name2;
+ @end
+
+ @implementation Person (MyCategory)
+ - (void)someMethodName2:(void*)name2 {
+ int foo2;
+ }
+ @end
+
+ @protocol MyProtocol
+ - (void)someMethodName3:(void*)name3;
+ @end
+ )";
+ TestFileName = "test.m";
+ runSymbolCollector(Header, /*Main=*/"", {"-fblocks", "-xobjective-c++"});
+ EXPECT_THAT(Symbols,
+ UnorderedElementsAre(
+ QName("Person"), QName("Person::someMethodName:lastName:"),
+ QName("MyCategory"), QName("Person::someMethodName2:"),
+ QName("MyProtocol"), QName("MyProtocol::someMethodName3:")));
}
TEST_F(SymbolCollectorTest, Locations) {
Green
};
enum class Color2 {
- Yellow // ignore
+ Yellow
};
namespace ns {
enum {
}
)";
runSymbolCollector(Header, /*Main=*/"");
- EXPECT_THAT(Symbols, UnorderedElementsAre(QName("Red"), QName("Color"),
- QName("Green"), QName("Color2"),
- QName("ns"), QName("ns::Black")));
+ EXPECT_THAT(Symbols,
+ UnorderedElementsAre(
+ AllOf(QName("Red"), ForCodeCompletion(true)),
+ AllOf(QName("Color"), ForCodeCompletion(true)),
+ AllOf(QName("Green"), ForCodeCompletion(true)),
+ AllOf(QName("Color2"), ForCodeCompletion(true)),
+ AllOf(QName("Color2::Yellow"), ForCodeCompletion(false)),
+ AllOf(QName("ns"), ForCodeCompletion(true)),
+ AllOf(QName("ns::Black"), ForCodeCompletion(true))));
}
-TEST_F(SymbolCollectorTest, IgnoreNamelessSymbols) {
+TEST_F(SymbolCollectorTest, NamelessSymbols) {
const std::string Header = R"(
struct {
int a;
} Foo;
)";
runSymbolCollector(Header, /*Main=*/"");
- EXPECT_THAT(Symbols,
- UnorderedElementsAre(QName("Foo")));
+ EXPECT_THAT(Symbols, UnorderedElementsAre(QName("Foo"),
+ QName("(anonymous struct)::a")));
}
TEST_F(SymbolCollectorTest, SymbolFormedFromMacro) {
UnorderedElementsAre(QName("Foo"), QName("f1"), QName("f2")));
}
-TEST_F(SymbolCollectorTest, IgnoreClassMembers) {
+TEST_F(SymbolCollectorTest, ClassMembers) {
const std::string Header = R"(
class Foo {
void f() {}
void Foo::ssf() {}
)";
runSymbolCollector(Header, Main);
- EXPECT_THAT(Symbols, UnorderedElementsAre(QName("Foo")));
+ EXPECT_THAT(Symbols,
+ UnorderedElementsAre(QName("Foo"), QName("Foo::f"),
+ QName("Foo::g"), QName("Foo::sf"),
+ QName("Foo::ssf"), QName("Foo::x")));
}
TEST_F(SymbolCollectorTest, Scopes) {
End:
Line: 1
Column: 1
+IsIndexedForCodeCompletion: true
CompletionLabel: 'Foo1-label'
CompletionFilterText: 'filter'
CompletionPlainInsertText: 'plain'
End:
Line: 1
Column: 1
+IsIndexedForCodeCompletion: false
CompletionLabel: 'Foo2-label'
CompletionFilterText: 'filter'
CompletionPlainInsertText: 'plain'
EXPECT_THAT(Symbols1,
UnorderedElementsAre(AllOf(
QName("clang::Foo1"), Labeled("Foo1-label"), Doc("Foo doc"),
- Detail("int"), DeclURI("file:///path/foo.h"))));
+ Detail("int"), DeclURI("file:///path/foo.h"),
+ ForCodeCompletion(true))));
auto Symbols2 = SymbolsFromYAML(YAML2);
- EXPECT_THAT(Symbols2, UnorderedElementsAre(AllOf(
- QName("clang::Foo2"), Labeled("Foo2-label"),
- Not(HasDetail()), DeclURI("file:///path/bar.h"))));
+ EXPECT_THAT(Symbols2,
+ UnorderedElementsAre(AllOf(
+ QName("clang::Foo2"), Labeled("Foo2-label"), Not(HasDetail()),
+ DeclURI("file:///path/bar.h"), ForCodeCompletion(false))));
std::string ConcatenatedYAML;
{
// Canonical declarations.
class $cdecl[[C]] {};
struct $sdecl[[S]] {};
- union $udecl[[U]] {int x; bool y;};
+ union $udecl[[U]] {int $xdecl[[x]]; bool $ydecl[[y]];};
)");
runSymbolCollector(Header.code(), /*Main=*/"");
- EXPECT_THAT(Symbols,
- UnorderedElementsAre(
- AllOf(QName("C"), DeclURI(TestHeaderURI),
- DeclRange(Header.range("cdecl")),
- IncludeHeader(TestHeaderURI), DefURI(TestHeaderURI),
- DefRange(Header.range("cdecl"))),
- AllOf(QName("S"), DeclURI(TestHeaderURI),
- DeclRange(Header.range("sdecl")),
- IncludeHeader(TestHeaderURI), DefURI(TestHeaderURI),
- DefRange(Header.range("sdecl"))),
- AllOf(QName("U"), DeclURI(TestHeaderURI),
- DeclRange(Header.range("udecl")),
- IncludeHeader(TestHeaderURI), DefURI(TestHeaderURI),
- DefRange(Header.range("udecl")))));
+ EXPECT_THAT(
+ Symbols,
+ UnorderedElementsAre(
+ AllOf(QName("C"), DeclURI(TestHeaderURI),
+ DeclRange(Header.range("cdecl")), IncludeHeader(TestHeaderURI),
+ DefURI(TestHeaderURI), DefRange(Header.range("cdecl"))),
+ AllOf(QName("S"), DeclURI(TestHeaderURI),
+ DeclRange(Header.range("sdecl")), IncludeHeader(TestHeaderURI),
+ DefURI(TestHeaderURI), DefRange(Header.range("sdecl"))),
+ AllOf(QName("U"), DeclURI(TestHeaderURI),
+ DeclRange(Header.range("udecl")), IncludeHeader(TestHeaderURI),
+ DefURI(TestHeaderURI), DefRange(Header.range("udecl"))),
+ AllOf(QName("U::x"), DeclURI(TestHeaderURI),
+ DeclRange(Header.range("xdecl")), DefURI(TestHeaderURI),
+ DefRange(Header.range("xdecl"))),
+ AllOf(QName("U::y"), DeclURI(TestHeaderURI),
+ DeclRange(Header.range("ydecl")), DefURI(TestHeaderURI),
+ DefRange(Header.range("ydecl")))));
}
TEST_F(SymbolCollectorTest, ClassForwardDeclarationIsCanonical) {