1 //===- NamespaceEndCommentsFixerTest.cpp - Formatting unit tests ----------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "clang/Format/Format.h"
11 
12 #include "clang/Frontend/TextDiagnosticPrinter.h"
13 #include "llvm/Support/Debug.h"
14 #include "gtest/gtest.h"
15 
16 #define DEBUG_TYPE "namespace-end-comments-fixer-test"
17 
18 namespace clang {
19 namespace format {
20 namespace {
21 
22 class NamespaceEndCommentsFixerTest : public ::testing::Test {
23 protected:
24   std::string
25   fixNamespaceEndComments(llvm::StringRef Code,
26                           std::vector<tooling::Range> Ranges,
27                           const FormatStyle &Style = getLLVMStyle()) {
28     DEBUG(llvm::errs() << "---\n");
29     DEBUG(llvm::errs() << Code << "\n\n");
30     tooling::Replacements Replaces =
31         clang::format::fixNamespaceEndComments(Style, Code, Ranges, "<stdin>");
32     auto Result = applyAllReplacements(Code, Replaces);
33     EXPECT_TRUE(static_cast<bool>(Result));
34     DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
35     return *Result;
36   }
37 
38   std::string
39   fixNamespaceEndComments(llvm::StringRef Code,
40                           const FormatStyle &Style = getLLVMStyle()) {
41     return fixNamespaceEndComments(
42         Code,
43         /*Ranges=*/{1, tooling::Range(0, Code.size())}, Style);
44   }
45 };
46 
47 TEST_F(NamespaceEndCommentsFixerTest, AddsEndComment) {
48   EXPECT_EQ("namespace {\n"
49             "  int i;\n"
50             "  int j;\n"
51             "}// namespace",
52             fixNamespaceEndComments("namespace {\n"
53                                     "  int i;\n"
54                                     "  int j;\n"
55                                     "}"));
56   EXPECT_EQ("namespace {\n"
57             "  int i;\n"
58             "  int j;\n"
59             "}// namespace\n",
60             fixNamespaceEndComments("namespace {\n"
61                                     "  int i;\n"
62                                     "  int j;\n"
63                                     "}\n"));
64   EXPECT_EQ("namespace A {\n"
65             "  int i;\n"
66             "  int j;\n"
67             "}// namespace A",
68             fixNamespaceEndComments("namespace A {\n"
69                                     "  int i;\n"
70                                     "  int j;\n"
71                                     "}"));
72   EXPECT_EQ("inline namespace A {\n"
73             "  int i;\n"
74             "  int j;\n"
75             "}// namespace A",
76             fixNamespaceEndComments("inline namespace A {\n"
77                                     "  int i;\n"
78                                     "  int j;\n"
79                                     "}"));
80   EXPECT_EQ("namespace ::A {\n"
81             "  int i;\n"
82             "  int j;\n"
83             "}// namespace ::A",
84             fixNamespaceEndComments("namespace ::A {\n"
85                                     "  int i;\n"
86                                     "  int j;\n"
87                                     "}"));
88   EXPECT_EQ("namespace ::A::B {\n"
89             "  int i;\n"
90             "  int j;\n"
91             "}// namespace ::A::B",
92             fixNamespaceEndComments("namespace ::A::B {\n"
93                                     "  int i;\n"
94                                     "  int j;\n"
95                                     "}"));
96   EXPECT_EQ("namespace /**/::/**/A/**/::/**/B/**/ {\n"
97             "  int i;\n"
98             "  int j;\n"
99             "}// namespace ::A::B",
100             fixNamespaceEndComments("namespace /**/::/**/A/**/::/**/B/**/ {\n"
101                                     "  int i;\n"
102                                     "  int j;\n"
103                                     "}"));
104   EXPECT_EQ("namespace A {\n"
105             "namespace B {\n"
106             "  int i;\n"
107             "}\n"
108             "}// namespace A",
109             fixNamespaceEndComments("namespace A {\n"
110                                     "namespace B {\n"
111                                     "  int i;\n"
112                                     "}\n"
113                                     "}"));
114   EXPECT_EQ("namespace A {\n"
115             "namespace B {\n"
116             "  int i;\n"
117             "  int j;\n"
118             "}// namespace B\n"
119             "}// namespace A",
120             fixNamespaceEndComments("namespace A {\n"
121                                     "namespace B {\n"
122                                     "  int i;\n"
123                                     "  int j;\n"
124                                     "}\n"
125                                     "}"));
126   EXPECT_EQ("namespace A {\n"
127             "  int a;\n"
128             "  int b;\n"
129             "}// namespace A\n"
130             "namespace B {\n"
131             "  int b;\n"
132             "  int a;\n"
133             "}// namespace B",
134             fixNamespaceEndComments("namespace A {\n"
135                                     "  int a;\n"
136                                     "  int b;\n"
137                                     "}\n"
138                                     "namespace B {\n"
139                                     "  int b;\n"
140                                     "  int a;\n"
141                                     "}"));
142   EXPECT_EQ("namespace A {\n"
143             "  int a1;\n"
144             "  int a2;\n"
145             "}// namespace A\n"
146             "namespace A {\n"
147             "  int a2;\n"
148             "  int a1;\n"
149             "}// namespace A",
150             fixNamespaceEndComments("namespace A {\n"
151                                     "  int a1;\n"
152                                     "  int a2;\n"
153                                     "}\n"
154                                     "namespace A {\n"
155                                     "  int a2;\n"
156                                     "  int a1;\n"
157                                     "}"));
158   EXPECT_EQ("namespace A {\n"
159             "  int a;\n"
160             "  int b;\n"
161             "}// namespace A\n"
162             "// comment about b\n"
163             "int b;",
164             fixNamespaceEndComments("namespace A {\n"
165                                     "  int a;\n"
166                                     "  int b;\n"
167                                     "}\n"
168                                     "// comment about b\n"
169                                     "int b;"));
170 
171   EXPECT_EQ("namespace A {\n"
172             "namespace B {\n"
173             "namespace C {\n"
174             "namespace D {\n"
175             "}\n"
176             "}// namespace C\n"
177             "}// namespace B\n"
178             "}// namespace A",
179             fixNamespaceEndComments("namespace A {\n"
180                                     "namespace B {\n"
181                                     "namespace C {\n"
182                                     "namespace D {\n"
183                                     "}\n"
184                                     "}\n"
185                                     "}\n"
186                                     "}"));
187 }
188 
189 TEST_F(NamespaceEndCommentsFixerTest, AddsNewlineIfNeeded) {
190   EXPECT_EQ("namespace A {\n"
191             "  int i;\n"
192             "  int j;\n"
193             "}// namespace A\n"
194             " int k;",
195             fixNamespaceEndComments("namespace A {\n"
196                                     "  int i;\n"
197                                     "  int j;\n"
198                                     "} int k;"));
199   EXPECT_EQ("namespace {\n"
200             "  int i;\n"
201             "  int j;\n"
202             "}// namespace\n"
203             " int k;",
204             fixNamespaceEndComments("namespace {\n"
205                                     "  int i;\n"
206                                     "  int j;\n"
207                                     "} int k;"));
208   EXPECT_EQ("namespace A {\n"
209             "  int i;\n"
210             "  int j;\n"
211             "}// namespace A\n"
212             " namespace B {\n"
213             "  int j;\n"
214             "  int k;\n"
215             "}// namespace B",
216             fixNamespaceEndComments("namespace A {\n"
217                                     "  int i;\n"
218                                     "  int j;\n"
219                                     "} namespace B {\n"
220                                     "  int j;\n"
221                                     "  int k;\n"
222                                     "}"));
223 }
224 
225 TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddEndCommentForShortNamespace) {
226   EXPECT_EQ("namespace {}", fixNamespaceEndComments("namespace {}"));
227   EXPECT_EQ("namespace A {}", fixNamespaceEndComments("namespace A {}"));
228   EXPECT_EQ("namespace A { a }",
229             fixNamespaceEndComments("namespace A { a }"));
230 }
231 
232 TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddCommentAfterUnaffectedRBrace) {
233   EXPECT_EQ("namespace A {\n"
234             "  int i;\n"
235             "}",
236             fixNamespaceEndComments("namespace A {\n"
237                                     "  int i;\n"
238                                     "}",
239                                     // The range (16, 3) spans the 'int' above.
240                                     /*Ranges=*/{1, tooling::Range(16, 3)}));
241 }
242 
243 TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddCommentAfterRBraceInPPDirective) {
244   EXPECT_EQ("#define SAD \\\n"
245             "namespace A { \\\n"
246             "  int i; \\\n"
247             "}",
248             fixNamespaceEndComments("#define SAD \\\n"
249                                     "namespace A { \\\n"
250                                     "  int i; \\\n"
251                                     "}"));
252 }
253 
254 TEST_F(NamespaceEndCommentsFixerTest, KeepsValidEndComment) {
255   EXPECT_EQ("namespace {\n"
256             "  int i;\n"
257             "} // end anonymous namespace",
258             fixNamespaceEndComments("namespace {\n"
259                                     "  int i;\n"
260                                     "} // end anonymous namespace"));
261   EXPECT_EQ("namespace A {\n"
262             "  int i;\n"
263             "} /* end of namespace A */",
264             fixNamespaceEndComments("namespace A {\n"
265                                     "  int i;\n"
266                                     "} /* end of namespace A */"));
267   EXPECT_EQ("namespace A {\n"
268             "  int i;\n"
269             "}   //   namespace A",
270             fixNamespaceEndComments("namespace A {\n"
271                                     "  int i;\n"
272                                     "}   //   namespace A"));
273   EXPECT_EQ("namespace A::B {\n"
274             "  int i;\n"
275             "} // end namespace A::B",
276             fixNamespaceEndComments("namespace A::B {\n"
277                                     "  int i;\n"
278                                     "} // end namespace A::B"));
279 }
280 
281 TEST_F(NamespaceEndCommentsFixerTest, UpdatesInvalidEndLineComment) {
282   EXPECT_EQ("namespace {\n"
283             "  int i;\n"
284             "} // namespace",
285             fixNamespaceEndComments("namespace {\n"
286                                     "  int i;\n"
287                                     "} // namespace A"));
288   EXPECT_EQ("namespace A {\n"
289             "  int i;\n"
290             "} // namespace A",
291             fixNamespaceEndComments("namespace A {\n"
292                                     "  int i;\n"
293                                     "} // namespace"));
294   EXPECT_EQ("namespace A {\n"
295             "  int i;\n"
296             "} // namespace A",
297             fixNamespaceEndComments("namespace A {\n"
298                                     "  int i;\n"
299                                     "} //"));
300   EXPECT_EQ("namespace A {\n"
301             "  int i;\n"
302             "} // namespace A",
303             fixNamespaceEndComments("namespace A {\n"
304                                     "  int i;\n"
305                                     "} //"));
306   EXPECT_EQ("namespace A {\n"
307             "  int i;\n"
308             "} // namespace A",
309             fixNamespaceEndComments("namespace A {\n"
310                                     "  int i;\n"
311                                     "} // banamespace A"));
312 
313   // Updates invalid line comments even for short namespaces.
314   EXPECT_EQ("namespace A {} // namespace A",
315             fixNamespaceEndComments("namespace A {} // namespace"));
316 }
317 
318 TEST_F(NamespaceEndCommentsFixerTest, UpdatesInvalidEndBlockComment) {
319   EXPECT_EQ("namespace {\n"
320             "  int i;\n"
321             "} // namespace",
322             fixNamespaceEndComments("namespace {\n"
323                                     "  int i;\n"
324                                     "} /* namespace A */"));
325   EXPECT_EQ("namespace A {\n"
326             "  int i;\n"
327             "}  // namespace A",
328             fixNamespaceEndComments("namespace A {\n"
329                                     "  int i;\n"
330                                     "}  /* end namespace */"));
331   EXPECT_EQ("namespace A {\n"
332             "  int i;\n"
333             "} // namespace A",
334             fixNamespaceEndComments("namespace A {\n"
335                                     "  int i;\n"
336                                     "} /**/"));
337   EXPECT_EQ("namespace A {\n"
338             "  int i;\n"
339             "} // namespace A",
340             fixNamespaceEndComments("namespace A {\n"
341                                     "  int i;\n"
342                                     "} /* end unnamed namespace */"));
343   EXPECT_EQ("namespace A {\n"
344             "  int i;\n"
345             "} // namespace A",
346             fixNamespaceEndComments("namespace A {\n"
347                                     "  int i;\n"
348                                     "} /* banamespace A */"));
349   EXPECT_EQ("namespace A {} // namespace A",
350             fixNamespaceEndComments("namespace A {} /**/"));
351 }
352 
353 TEST_F(NamespaceEndCommentsFixerTest,
354        DoesNotAddEndCommentForNamespacesControlledByMacros) {
355   EXPECT_EQ("#ifdef 1\n"
356             "namespace A {\n"
357             "#elseif\n"
358             "namespace B {\n"
359             "#endif\n"
360             "  int i;\n"
361             "}\n"
362             "}\n",
363             fixNamespaceEndComments("#ifdef 1\n"
364                                     "namespace A {\n"
365                                     "#elseif\n"
366                                     "namespace B {\n"
367                                     "#endif\n"
368                                     "  int i;\n"
369                                     "}\n"
370                                     "}\n"));
371 }
372 
373 TEST_F(NamespaceEndCommentsFixerTest,
374        DoesNotAddEndCommentForNamespacesInMacroDeclarations) {
375   EXPECT_EQ("#ifdef 1\n"
376             "namespace A {\n"
377             "#elseif\n"
378             "namespace B {\n"
379             "#endif\n"
380             "  int i;\n"
381             "}\n"
382             "}\n",
383             fixNamespaceEndComments("#ifdef 1\n"
384                                     "namespace A {\n"
385                                     "#elseif\n"
386                                     "namespace B {\n"
387                                     "#endif\n"
388                                     "  int i;\n"
389                                     "}\n"
390                                     "}\n"));
391 }
392 
393 TEST_F(NamespaceEndCommentsFixerTest,
394        DoesNotAddEndCommentForUnbalancedRBracesAfterNamespaceEnd) {
395   EXPECT_EQ("namespace {\n"
396             "  int i;\n"
397             "} // namespace\n"
398             "}",
399             fixNamespaceEndComments("namespace {\n"
400                                     "  int i;\n"
401                                     "} // namespace\n"
402                                     "}"));
403 }
404 } // end namespace
405 } // end namespace format
406 } // end namespace clang
407