xref: /llvm-project/clang/unittests/Interpreter/CodeCompletionTest.cpp (revision 9ebe6e28cdbe97f6c03209b87e91be6b55a8026a)
1 #include "clang/Interpreter/CodeCompletion.h"
2 #include "clang/Frontend/CompilerInstance.h"
3 #include "clang/Interpreter/Interpreter.h"
4 #include "clang/Sema/CodeCompleteConsumer.h"
5 #include "llvm/LineEditor/LineEditor.h"
6 #include "llvm/Support/Error.h"
7 #include "llvm/Support/raw_ostream.h"
8 
9 #include "gmock/gmock.h"
10 #include "gtest/gtest.h"
11 
12 using namespace clang;
13 namespace {
14 auto CB = clang::IncrementalCompilerBuilder();
15 
16 static std::unique_ptr<Interpreter> createInterpreter() {
17   auto CI = cantFail(CB.CreateCpp());
18   return cantFail(clang::Interpreter::create(std::move(CI)));
19 }
20 
21 static std::vector<std::string> runComp(clang::Interpreter &MainInterp,
22                                         llvm::StringRef Prefix,
23                                         llvm::Error &ErrR) {
24   auto CI = CB.CreateCpp();
25   if (auto Err = CI.takeError()) {
26     ErrR = std::move(Err);
27     return {};
28   }
29 
30   auto Interp = clang::Interpreter::create(std::move(*CI));
31   if (auto Err = Interp.takeError()) {
32     // log the error and returns an empty vector;
33     ErrR = std::move(Err);
34 
35     return {};
36   }
37 
38   std::vector<std::string> Results;
39   std::vector<std::string> Comps;
40 
41   codeComplete(
42       const_cast<clang::CompilerInstance *>((*Interp)->getCompilerInstance()),
43       Prefix, /* Lines */ 1, Prefix.size(), MainInterp.getCompilerInstance(),
44       Results);
45 
46   for (auto Res : Results)
47     if (Res.find(Prefix) == 0)
48       Comps.push_back(Res);
49 
50   return Comps;
51 }
52 
53 #ifdef _AIX
54 TEST(CodeCompletionTest, DISABLED_Sanity) {
55 #else
56 TEST(CodeCompletionTest, Sanity) {
57 #endif
58   auto Interp = createInterpreter();
59   if (auto R = Interp->ParseAndExecute("int foo = 12;")) {
60     consumeError(std::move(R));
61     return;
62   }
63   auto Err = llvm::Error::success();
64   auto comps = runComp(*Interp, "f", Err);
65   EXPECT_EQ((size_t)2, comps.size()); // foo and float
66   EXPECT_EQ(comps[0], std::string("foo"));
67   EXPECT_EQ((bool)Err, false);
68 }
69 
70 #ifdef _AIX
71 TEST(CodeCompletionTest, DISABLED_SanityNoneValid) {
72 #else
73 TEST(CodeCompletionTest, SanityNoneValid) {
74 #endif
75   auto Interp = createInterpreter();
76   if (auto R = Interp->ParseAndExecute("int foo = 12;")) {
77     consumeError(std::move(R));
78     return;
79   }
80   auto Err = llvm::Error::success();
81   auto comps = runComp(*Interp, "babanana", Err);
82   EXPECT_EQ((size_t)0, comps.size()); // foo and float
83   EXPECT_EQ((bool)Err, false);
84 }
85 
86 #ifdef _AIX
87 TEST(CodeCompletionTest, DISABLED_TwoDecls) {
88 #else
89 TEST(CodeCompletionTest, TwoDecls) {
90 #endif
91   auto Interp = createInterpreter();
92   if (auto R = Interp->ParseAndExecute("int application = 12;")) {
93     consumeError(std::move(R));
94     return;
95   }
96   if (auto R = Interp->ParseAndExecute("int apple = 12;")) {
97     consumeError(std::move(R));
98     return;
99   }
100   auto Err = llvm::Error::success();
101   auto comps = runComp(*Interp, "app", Err);
102   EXPECT_EQ((size_t)2, comps.size());
103   EXPECT_EQ((bool)Err, false);
104 }
105 
106 TEST(CodeCompletionTest, CompFunDeclsNoError) {
107   auto Interp = createInterpreter();
108   auto Err = llvm::Error::success();
109   auto comps = runComp(*Interp, "void app(", Err);
110   EXPECT_EQ((bool)Err, false);
111 }
112 
113 } // anonymous namespace
114