xref: /llvm-project/clang-tools-extra/clangd/unittests/FeatureModulesTests.cpp (revision bd89f9ec293ea5e20e89d4bce49135431239cf3e)
1 //===--- FeatureModulesTests.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 "FeatureModule.h"
11 #include "Selection.h"
12 #include "TestTU.h"
13 #include "refactor/Tweak.h"
14 #include "support/Logger.h"
15 #include "clang/Lex/PreprocessorOptions.h"
16 #include "llvm/Support/Error.h"
17 #include "gmock/gmock.h"
18 #include "gtest/gtest.h"
19 #include <memory>
20 
21 namespace clang {
22 namespace clangd {
23 namespace {
24 
TEST(FeatureModulesTest,ContributesTweak)25 TEST(FeatureModulesTest, ContributesTweak) {
26   static constexpr const char *TweakID = "ModuleTweak";
27   struct TweakContributingModule final : public FeatureModule {
28     struct ModuleTweak final : public Tweak {
29       const char *id() const override { return TweakID; }
30       bool prepare(const Selection &Sel) override { return true; }
31       Expected<Effect> apply(const Selection &Sel) override {
32         return error("not implemented");
33       }
34       std::string title() const override { return id(); }
35       llvm::StringLiteral kind() const override {
36         return llvm::StringLiteral("");
37       };
38     };
39 
40     void contributeTweaks(std::vector<std::unique_ptr<Tweak>> &Out) override {
41       Out.emplace_back(new ModuleTweak);
42     }
43   };
44 
45   FeatureModuleSet Set;
46   Set.add(std::make_unique<TweakContributingModule>());
47 
48   auto AST = TestTU::withCode("").build();
49   auto Tree =
50       SelectionTree::createRight(AST.getASTContext(), AST.getTokens(), 0, 0);
51   auto Actual = prepareTweak(
52       TweakID, Tweak::Selection(nullptr, AST, 0, 0, std::move(Tree), nullptr),
53       &Set);
54   ASSERT_TRUE(bool(Actual));
55   EXPECT_EQ(Actual->get()->id(), TweakID);
56 }
57 
TEST(FeatureModulesTest,SuppressDiags)58 TEST(FeatureModulesTest, SuppressDiags) {
59   struct DiagModifierModule final : public FeatureModule {
60     struct Listener : public FeatureModule::ASTListener {
61       void sawDiagnostic(const clang::Diagnostic &Info,
62                          clangd::Diag &Diag) override {
63         Diag.Severity = DiagnosticsEngine::Ignored;
64       }
65     };
66     std::unique_ptr<ASTListener> astListeners() override {
67       return std::make_unique<Listener>();
68     };
69   };
70   FeatureModuleSet FMS;
71   FMS.add(std::make_unique<DiagModifierModule>());
72 
73   Annotations Code("[[test]]; /* error-ok */");
74   TestTU TU;
75   TU.Code = Code.code().str();
76 
77   {
78     auto AST = TU.build();
79     EXPECT_THAT(AST.getDiagnostics(), testing::Not(testing::IsEmpty()));
80   }
81 
82   TU.FeatureModules = &FMS;
83   {
84     auto AST = TU.build();
85     EXPECT_THAT(AST.getDiagnostics(), testing::IsEmpty());
86   }
87 }
88 
TEST(FeatureModulesTest,BeforeExecute)89 TEST(FeatureModulesTest, BeforeExecute) {
90   struct BeforeExecuteModule final : public FeatureModule {
91     struct Listener : public FeatureModule::ASTListener {
92       void beforeExecute(CompilerInstance &CI) override {
93         CI.getPreprocessor().SetSuppressIncludeNotFoundError(true);
94       }
95     };
96     std::unique_ptr<ASTListener> astListeners() override {
97       return std::make_unique<Listener>();
98     };
99   };
100   FeatureModuleSet FMS;
101   FMS.add(std::make_unique<BeforeExecuteModule>());
102 
103   TestTU TU = TestTU::withCode(R"cpp(
104     /*error-ok*/
105     #include "not_found.h"
106 
107     void foo() {
108       #include "not_found_not_preamble.h"
109     }
110   )cpp");
111 
112   {
113     auto AST = TU.build();
114     EXPECT_THAT(AST.getDiagnostics(), testing::Not(testing::IsEmpty()));
115   }
116 
117   TU.FeatureModules = &FMS;
118   {
119     auto AST = TU.build();
120     EXPECT_THAT(AST.getDiagnostics(), testing::IsEmpty());
121   }
122 }
123 
124 } // namespace
125 } // namespace clangd
126 } // namespace clang
127