clang-tools 10.0.0

SemanticSelectionTests.cpp
Go to the documentation of this file.
1 //===-- SemanticSelectionTests.cpp ----------------*- C++ -*--------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "Annotations.h"
10 #include "ClangdServer.h"
11 #include "Matchers.h"
12 #include "Protocol.h"
13 #include "SemanticSelection.h"
14 #include "SourceCode.h"
15 #include "SyncAPI.h"
16 #include "TestFS.h"
17 #include "TestTU.h"
18 #include "clang/Basic/SourceLocation.h"
19 #include "clang/Basic/SourceManager.h"
20 #include "llvm/Support/Error.h"
21 #include "gmock/gmock.h"
22 #include "gtest/gtest.h"
23 #include <vector>
24 namespace clang {
25 namespace clangd {
26 namespace {
27 using ::testing::ElementsAreArray;
28
29 class IgnoreDiagnostics : public DiagnosticsConsumer {
30 void onDiagnosticsReady(PathRef File,
31 std::vector<Diag> Diagnostics) override {}
32 };
33
34 TEST(SemanticSelection, All) {
35 const char *Tests[] = {
36 R"cpp( // Single statement in a function body.
37 [[void func() [[{
38 [[[[int v = [[1^00]]]];]]
39 }]]]]
40 )cpp",
41 R"cpp( // Expression
42 [[void func() [[{
43 int a = 1;
44 // int v = (10 + 2) * (a + a);
45 [[[[int v = [[[[([[[[10^]] + 2]])]] * (a + a)]]]];]]
46 }]]]]
47 )cpp",
48 R"cpp( // Function call.
49 int add(int x, int y) { return x + y; }
50 [[void callee() [[{
51 // int res = add(11, 22);
52 [[[[int res = [[add([[1^1]], 22)]]]];]]
53 }]]]]
54 )cpp",
55 R"cpp( // Tricky macros.
56 #define MUL ) * (
57 [[void func() [[{
58 // int var = (4 + 15 MUL 6 + 10);
59 [[[[int var = [[[[([[4 + [[1^5]]]] MUL]] 6 + 10)]]]];]]
60 }]]]]
61 )cpp",
62 R"cpp( // Cursor inside a macro.
63 #define HASH(x) ((x) % 10)
64 [[void func() [[{
65 [[[[int a = [[HASH([[[[2^3]] + 34]])]]]];]]
66 }]]]]
67 )cpp",
68 R"cpp( // Cursor on a macro.
69 #define HASH(x) ((x) % 10)
70 [[void func() [[{
71 [[[[int a = [[HA^SH(23)]]]];]]
72 }]]]]
73 )cpp",
74 R"cpp( // Multiple declaration.
75 [[void func() [[{
76 [[[[int var1, var^2]], var3;]]
77 }]]]]
78 )cpp",
79 R"cpp( // Before comment.
80 [[void func() [[{
81 int var1 = 1;
82 [[[[int var2 = [[[[var1]]^ /*some comment*/ + 41]]]];]]
83 }]]]]
84 )cpp",
85 // Empty file.
86 "^",
87 // FIXME: We should get the whole DeclStmt as a range.
88 R"cpp( // Single statement in TU.
89 [[int v = [[1^00]]]];
90 )cpp",
91 R"cpp( // Cursor at end of VarDecl.
92 [[int v = [[100]]^]];
93 )cpp",
94 // FIXME: No node found associated to the position.
95 R"cpp( // Cursor in between spaces.
96 void func() {
97 int v = 100 + ^ 100;
98 }
99 )cpp",
100 // Structs.
101 R"cpp(
102 struct AAA { struct BBB { static int ccc(); };};
103 [[void func() [[{
104 // int x = AAA::BBB::ccc();
105 [[[[int x = [[[[AAA::BBB::c^cc]]()]]]];]]
106 }]]]]
107 )cpp",
108 R"cpp(
109 struct AAA { struct BBB { static int ccc(); };};
110 [[void func() [[{
111 // int x = AAA::BBB::ccc();
112 [[[[int x = [[[[[[[[[[AA^A]]::]]BBB::]]ccc]]()]]]];]]
113 }]]]]
114 )cpp",
115 R"cpp( // Inside struct.
116 struct A { static int a(); };
117 [[struct B {
118 [[static int b() [[{
119 [[return [[[[1^1]] + 2]]]];
120 }]]]]
121 }]];
122 )cpp",
123 // Namespaces.
124 R"cpp(
125 [[namespace nsa {
126 [[namespace nsb {
127 static int ccc();
128 [[void func() [[{
129 // int x = nsa::nsb::ccc();
130 [[[[int x = [[[[nsa::nsb::cc^c]]()]]]];]]
131 }]]]]
132 }]]
133 }]]
134 )cpp",
135
136 };
137
138 for (const char *Test : Tests) {
139 auto T = Annotations(Test);
140 auto AST = TestTU::withCode(T.code()).build();
141 EXPECT_THAT(llvm::cantFail(getSemanticRanges(AST, T.point())),
142 ElementsAreArray(T.ranges()))
143 << Test;
144 }
145 }
146
147 TEST(SemanticSelection, RunViaClangDServer) {
148 MockFSProvider FS;
149 IgnoreDiagnostics DiagConsumer;
150 MockCompilationDatabase CDB;
151 ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
152
153 auto FooH = testPath("foo.h");
154 FS.Files[FooH] = R"cpp(
155 int foo(int x);
156 #define HASH(x) ((x) % 10)
157 )cpp";
158
159 auto FooCpp = testPath("Foo.cpp");
160 const char *SourceContents = R"cpp(
161 #include "foo.h"
162 [[void bar(int& inp) [[{
163 // inp = HASH(foo(inp));
164 [[inp = [[HASH([[foo([[in^p]])]])]]]];
165 }]]]]
166 )cpp";
167 Annotations SourceAnnotations(SourceContents);
168 FS.Files[FooCpp] = SourceAnnotations.code();
169 Server.addDocument(FooCpp, SourceAnnotations.code());
170
171 auto Ranges = runSemanticRanges(Server, FooCpp, SourceAnnotations.point());
172 ASSERT_TRUE(bool(Ranges))
173 << "getSemanticRange returned an error: " << Ranges.takeError();
174 EXPECT_THAT(*Ranges, ElementsAreArray(SourceAnnotations.ranges()));
175 }
176 } // namespace
177 } // namespace clangd
178 } // namespace clang
clang::clangd::runSemanticRanges
llvm::Expected< std::vector< Range > > runSemanticRanges(ClangdServer &Server, PathRef File, Position Pos)
Definition: SyncAPI.cpp:148
ClangdServer.h
SourceCode.h
Matchers.h
Protocol.h
clang::clangd::PathRef
llvm::StringRef PathRef
A typedef to represent a ref to file path.
Definition: Path.h:23
clang::clangd::RefKind::All
FS
MockFSProvider FS
Definition: HeadersTests.cpp:119
clang::clangd::ClangdServer::optsForTest
static Options optsForTest()
Definition: ClangdServer.cpp:103
TestFS.h
TestTU.h
clang::clangd::SymbolOrigin::AST
Annotations.h
clang::clangd::TEST
TEST(BackgroundQueueTest, Priority)
Definition: BackgroundIndexTests.cpp:647
clang::clangd::testPath
std::string testPath(PathRef File)
Definition: TestFS.cpp:82
clang::clangd::DiagnosticsConsumer::onDiagnosticsReady
virtual void onDiagnosticsReady(PathRef File, std::vector< Diag > Diagnostics)=0
Called by ClangdServer when Diagnostics for File are ready.
clang::clangd::getSemanticRanges
llvm::Expected< std::vector< Range > > getSemanticRanges(ParsedAST &AST, Position Pos)
Returns the list of all interesting ranges around the Position Pos.
Definition: SemanticSelection.cpp:29
SemanticSelection.h
clang::clangd::TestTU::withCode
static TestTU withCode(llvm::StringRef Code)
Definition: TestTU.h:33
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
Server
ClangdServer Server
Definition: FindSymbolsTests.cpp:70
SyncAPI.h
DiagConsumer
IgnoreDiagnostics DiagConsumer
Definition: FindSymbolsTests.cpp:69
clang::clangd::CompletionItemKind::File