|
18 | 18 | #include "TestTU.h" |
19 | 19 | #include "TidyProvider.h" |
20 | 20 | #include "URI.h" |
| 21 | +#include "refactor/Tweak.h" |
21 | 22 | #include "support/MemoryTree.h" |
22 | 23 | #include "support/Path.h" |
23 | 24 | #include "support/Threading.h" |
24 | 25 | #include "clang/Config/config.h" |
25 | 26 | #include "clang/Sema/CodeCompleteConsumer.h" |
26 | 27 | #include "clang/Tooling/ArgumentsAdjusters.h" |
| 28 | +#include "clang/Tooling/Core/Replacement.h" |
27 | 29 | #include "llvm/ADT/None.h" |
28 | 30 | #include "llvm/ADT/Optional.h" |
29 | 31 | #include "llvm/ADT/SmallVector.h" |
30 | 32 | #include "llvm/ADT/StringMap.h" |
31 | 33 | #include "llvm/ADT/StringRef.h" |
32 | 34 | #include "llvm/Support/Allocator.h" |
33 | 35 | #include "llvm/Support/Errc.h" |
| 36 | +#include "llvm/Support/Error.h" |
34 | 37 | #include "llvm/Support/Path.h" |
35 | 38 | #include "llvm/Support/Regex.h" |
36 | 39 | #include "llvm/Support/VirtualFileSystem.h" |
@@ -1259,6 +1262,60 @@ TEST(ClangdServer, MemoryUsageTest) { |
1259 | 1262 | ASSERT_TRUE(MT.children().count("tuscheduler")); |
1260 | 1263 | EXPECT_TRUE(MT.child("tuscheduler").children().count(FooCpp)); |
1261 | 1264 | } |
| 1265 | + |
| 1266 | +TEST(ClangdServer, RespectsTweakFormatting) { |
| 1267 | + static constexpr const char *TweakID = "ModuleTweak"; |
| 1268 | + static constexpr const char *NewContents = "{not;\nformatted;}"; |
| 1269 | + |
| 1270 | + // Contributes a tweak that generates a non-formatted insertion and disables |
| 1271 | + // formatting. |
| 1272 | + struct TweakContributingModule final : public FeatureModule { |
| 1273 | + struct ModuleTweak final : public Tweak { |
| 1274 | + const char *id() const override { return TweakID; } |
| 1275 | + bool prepare(const Selection &Sel) override { return true; } |
| 1276 | + Expected<Effect> apply(const Selection &Sel) override { |
| 1277 | + auto &SM = Sel.AST->getSourceManager(); |
| 1278 | + llvm::StringRef FilePath = SM.getFilename(Sel.Cursor); |
| 1279 | + tooling::Replacements Reps; |
| 1280 | + llvm::cantFail( |
| 1281 | + Reps.add(tooling::Replacement(FilePath, 0, 0, NewContents))); |
| 1282 | + auto E = llvm::cantFail(Effect::mainFileEdit(SM, std::move(Reps))); |
| 1283 | + E.FormatEdits = false; |
| 1284 | + return E; |
| 1285 | + } |
| 1286 | + std::string title() const override { return id(); } |
| 1287 | + llvm::StringLiteral kind() const override { |
| 1288 | + return llvm::StringLiteral(""); |
| 1289 | + }; |
| 1290 | + }; |
| 1291 | + |
| 1292 | + void contributeTweaks(std::vector<std::unique_ptr<Tweak>> &Out) override { |
| 1293 | + Out.emplace_back(new ModuleTweak); |
| 1294 | + } |
| 1295 | + }; |
| 1296 | + |
| 1297 | + MockFS FS; |
| 1298 | + MockCompilationDatabase CDB; |
| 1299 | + auto Opts = ClangdServer::optsForTest(); |
| 1300 | + FeatureModuleSet Set; |
| 1301 | + Set.add(std::make_unique<TweakContributingModule>()); |
| 1302 | + Opts.FeatureModules = &Set; |
| 1303 | + ClangdServer Server(CDB, FS, Opts); |
| 1304 | + |
| 1305 | + auto FooCpp = testPath("foo.cpp"); |
| 1306 | + Server.addDocument(FooCpp, ""); |
| 1307 | + ASSERT_TRUE(Server.blockUntilIdleForTest()); |
| 1308 | + |
| 1309 | + // Ensure that disabled formatting is respected. |
| 1310 | + Notification N; |
| 1311 | + Server.applyTweak(FooCpp, {}, TweakID, [&](llvm::Expected<Tweak::Effect> E) { |
| 1312 | + ASSERT_TRUE(static_cast<bool>(E)); |
| 1313 | + EXPECT_THAT(llvm::cantFail(E->ApplyEdits.lookup(FooCpp).apply()), |
| 1314 | + NewContents); |
| 1315 | + N.notify(); |
| 1316 | + }); |
| 1317 | + N.wait(); |
| 1318 | +} |
1262 | 1319 | } // namespace |
1263 | 1320 | } // namespace clangd |
1264 | 1321 | } // namespace clang |
0 commit comments