brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.9 KiB · ceb6834 Raw
248 lines · cpp
1//===- unittests/Interpreter/CodeCompletionTest.cpp -----------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "InterpreterTestFixture.h"10 11#include "clang/Interpreter/CodeCompletion.h"12#include "clang/Frontend/CompilerInstance.h"13#include "clang/Interpreter/Interpreter.h"14#include "clang/Lex/Preprocessor.h"15#include "clang/Sema/CodeCompleteConsumer.h"16#include "clang/Sema/Sema.h"17#include "llvm/LineEditor/LineEditor.h"18#include "llvm/Support/raw_ostream.h"19 20#include "gmock/gmock.h"21#include "gtest/gtest.h"22 23using namespace clang;24namespace {25auto CB = clang::IncrementalCompilerBuilder();26 27class CodeCompletionTest : public InterpreterTestBase {28public:29  std::unique_ptr<clang::Interpreter> Interp;30 31  void SetUp() override {32// FIXME : WebAssembly doesn't currently support Jit (see33// https: // github.com/llvm/llvm-project/pull/150977#discussion_r2237521095).34// so this check of HostSupportsJIT has been skipped35// over until support is added, and HostSupportsJIT can return true.36#ifndef __EMSCRIPTEN__37    if (!HostSupportsJIT())38      GTEST_SKIP();39#endif40    std::unique_ptr<CompilerInstance> CI = cantFail(CB.CreateCpp());41    this->Interp = cantFail(clang::Interpreter::create(std::move(CI)));42  }43 44  std::vector<std::string> runComp(llvm::StringRef Input, llvm::Error &ErrR) {45    auto ComplCI = CB.CreateCpp();46    if (auto Err = ComplCI.takeError()) {47      ErrR = std::move(Err);48      return {};49    }50 51    auto ComplInterp = clang::Interpreter::create(std::move(*ComplCI));52    if (auto Err = ComplInterp.takeError()) {53      ErrR = std::move(Err);54      return {};55    }56 57    std::vector<std::string> Results;58    std::vector<std::string> Comps;59    auto *ParentCI = this->Interp->getCompilerInstance();60    auto *MainCI = (*ComplInterp)->getCompilerInstance();61    auto CC = ReplCodeCompleter();62    CC.codeComplete(MainCI, Input, /* Lines */ 1, Input.size() + 1, ParentCI,63                    Results);64 65    for (auto Res : Results)66      if (Res.find(CC.Prefix) == 0)67        Comps.push_back(Res);68    return Comps;69  }70};71 72TEST_F(CodeCompletionTest, Sanity) {73  cantFail(Interp->Parse("int foo = 12;"));74  auto Err = llvm::Error::success();75  auto comps = runComp("f", Err);76  EXPECT_EQ((size_t)2, comps.size()); // float and foo77  EXPECT_EQ(comps[0], std::string("float"));78  EXPECT_EQ(comps[1], std::string("foo"));79  EXPECT_EQ((bool)Err, false);80}81 82TEST_F(CodeCompletionTest, SanityNoneValid) {83  cantFail(Interp->Parse("int foo = 12;"));84  auto Err = llvm::Error::success();85  auto comps = runComp("babanana", Err);86  EXPECT_EQ((size_t)0, comps.size()); // foo and float87  EXPECT_EQ((bool)Err, false);88}89 90TEST_F(CodeCompletionTest, TwoDecls) {91  cantFail(Interp->Parse("int application = 12;"));92  cantFail(Interp->Parse("int apple = 12;"));93  auto Err = llvm::Error::success();94  auto comps = runComp("app", Err);95  EXPECT_EQ((size_t)2, comps.size());96  EXPECT_EQ((bool)Err, false);97}98 99TEST_F(CodeCompletionTest, CompFunDeclsNoError) {100  auto Err = llvm::Error::success();101  auto comps = runComp("void app(", Err);102  EXPECT_EQ((bool)Err, false);103}104 105TEST_F(CodeCompletionTest, TypedDirected) {106  cantFail(Interp->Parse("int application = 12;"));107  cantFail(Interp->Parse("char apple = '2';"));108  cantFail(Interp->Parse("void add(int &SomeInt){}"));109  {110    auto Err = llvm::Error::success();111    auto comps = runComp(std::string("add("), Err);112    EXPECT_EQ((size_t)1, comps.size());113    EXPECT_EQ((bool)Err, false);114  }115 116  cantFail(Interp->Parse("int banana = 42;"));117 118  {119    auto Err = llvm::Error::success();120    auto comps = runComp(std::string("add("), Err);121    EXPECT_EQ((size_t)2, comps.size());122    EXPECT_EQ(comps[0], "application");123    EXPECT_EQ(comps[1], "banana");124    EXPECT_EQ((bool)Err, false);125  }126 127  {128    auto Err = llvm::Error::success();129    auto comps = runComp(std::string("add(b"), Err);130    EXPECT_EQ((size_t)1, comps.size());131    EXPECT_EQ(comps[0], "banana");132    EXPECT_EQ((bool)Err, false);133  }134}135 136TEST_F(CodeCompletionTest, SanityClasses) {137  cantFail(Interp->Parse("struct Apple{};"));138  cantFail(Interp->Parse("void takeApple(Apple &a1){}"));139  cantFail(Interp->Parse("Apple a1;"));140  cantFail(Interp->Parse("void takeAppleCopy(Apple a1){}"));141 142  {143    auto Err = llvm::Error::success();144    auto comps = runComp("takeApple(", Err);145    EXPECT_EQ((size_t)1, comps.size());146    EXPECT_EQ(comps[0], std::string("a1"));147    EXPECT_EQ((bool)Err, false);148  }149  {150    auto Err = llvm::Error::success();151    auto comps = runComp(std::string("takeAppleCopy("), Err);152    EXPECT_EQ((size_t)1, comps.size());153    EXPECT_EQ(comps[0], std::string("a1"));154    EXPECT_EQ((bool)Err, false);155  }156}157 158TEST_F(CodeCompletionTest, SubClassing) {159  cantFail(Interp->Parse("struct Fruit {};"));160  cantFail(Interp->Parse("struct Apple : Fruit{};"));161  cantFail(Interp->Parse("void takeFruit(Fruit &f){}"));162  cantFail(Interp->Parse("Apple a1;"));163  cantFail(Interp->Parse("Fruit f1;"));164  auto Err = llvm::Error::success();165  auto comps = runComp(std::string("takeFruit("), Err);166  EXPECT_EQ((size_t)2, comps.size());167  EXPECT_EQ(comps[0], std::string("a1"));168  EXPECT_EQ(comps[1], std::string("f1"));169  EXPECT_EQ((bool)Err, false);170}171 172TEST_F(CodeCompletionTest, MultipleArguments) {173  cantFail(Interp->Parse("int foo = 42;"));174  cantFail(Interp->Parse("char fowl = 'A';"));175  cantFail(Interp->Parse("void takeTwo(int &a, char b){}"));176  auto Err = llvm::Error::success();177  auto comps = runComp(std::string("takeTwo(foo,  "), Err);178  EXPECT_EQ((size_t)1, comps.size());179  EXPECT_EQ(comps[0], std::string("fowl"));180  EXPECT_EQ((bool)Err, false);181}182 183TEST_F(CodeCompletionTest, Methods) {184  cantFail(Interp->Parse(185      "struct Foo{int add(int a){return 42;} int par(int b){return 42;}};"));186  cantFail(Interp->Parse("Foo f1;"));187 188  auto Err = llvm::Error::success();189  auto comps = runComp(std::string("f1."), Err);190  EXPECT_EQ((size_t)2, comps.size());191  EXPECT_EQ(comps[0], std::string("add"));192  EXPECT_EQ(comps[1], std::string("par"));193  EXPECT_EQ((bool)Err, false);194}195 196TEST_F(CodeCompletionTest, MethodsInvocations) {197  cantFail(Interp->Parse(198      "struct Foo{int add(int a){return 42;} int par(int b){return 42;}};"));199  cantFail(Interp->Parse("Foo f1;"));200  cantFail(Interp->Parse("int a = 84;"));201 202  auto Err = llvm::Error::success();203  auto comps = runComp(std::string("f1.add("), Err);204  EXPECT_EQ((size_t)1, comps.size());205  EXPECT_EQ(comps[0], std::string("a"));206  EXPECT_EQ((bool)Err, false);207}208 209TEST_F(CodeCompletionTest, NestedInvocations) {210  cantFail(Interp->Parse(211      "struct Foo{int add(int a){return 42;} int par(int b){return 42;}};"));212  cantFail(Interp->Parse("Foo f1;"));213  cantFail(Interp->Parse("int a = 84;"));214  cantFail(Interp->Parse("int plus(int a, int b) { return a + b; }"));215 216  auto Err = llvm::Error::success();217  auto comps = runComp(std::string("plus(42, f1.add("), Err);218  EXPECT_EQ((size_t)1, comps.size());219  EXPECT_EQ(comps[0], std::string("a"));220  EXPECT_EQ((bool)Err, false);221}222 223TEST_F(CodeCompletionTest, TemplateFunctions) {224  cantFail(225      Interp->Parse("template <typename T> T id(T a) { return a;} "));226  cantFail(Interp->Parse("int apple = 84;"));227  {228    auto Err = llvm::Error::success();229    auto comps = runComp(std::string("id<int>("), Err);230    EXPECT_EQ((size_t)1, comps.size());231    EXPECT_EQ(comps[0], std::string("apple"));232    EXPECT_EQ((bool)Err, false);233  }234 235  cantFail(Interp->Parse(236      "template <typename T> T pickFirst(T a, T b) { return a;} "));237  cantFail(Interp->Parse("char pear = '4';"));238  {239    auto Err = llvm::Error::success();240    auto comps = runComp(std::string("pickFirst(apple, "), Err);241    EXPECT_EQ((size_t)1, comps.size());242    EXPECT_EQ(comps[0], std::string("apple"));243    EXPECT_EQ((bool)Err, false);244  }245}246 247} // anonymous namespace248