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 | |
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(Fmt: "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(args: new ModuleTweak); |
42 | } |
43 | }; |
44 | |
45 | FeatureModuleSet Set; |
46 | Set.add(M: std::make_unique<TweakContributingModule>()); |
47 | |
48 | auto AST = TestTU::withCode(Code: "" ).build(); |
49 | auto Tree = |
50 | SelectionTree::createRight(AST&: AST.getASTContext(), Tokens: AST.getTokens(), Begin: 0, End: 0); |
51 | auto Actual = prepareTweak( |
52 | ID: TweakID, S: Tweak::Selection(nullptr, AST, 0, 0, std::move(Tree), nullptr), |
53 | Modules: &Set); |
54 | ASSERT_TRUE(bool(Actual)); |
55 | EXPECT_EQ(Actual->get()->id(), TweakID); |
56 | } |
57 | |
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(M: 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 | |
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(M: std::make_unique<BeforeExecuteModule>()); |
102 | |
103 | TestTU TU = TestTU::withCode(Code: 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 | |