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