Skip to content

Commit

Permalink
[clangd] Add a flag to disable formatting of tweak edits
Browse files Browse the repository at this point in the history
Some tweaks might edit file types not supported by clang-format. This
patch gives them a way to signal that they do not require formatting.

Differential Revision: https://reviews.llvm.org/D105039
  • Loading branch information
kadircet committed Jun 28, 2021
1 parent 280593b commit 614b46e
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 2 deletions.
4 changes: 2 additions & 2 deletions clang-tools-extra/clangd/ClangdServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -637,8 +637,8 @@ void ClangdServer::applyTweak(PathRef File, Range Sel, StringRef TweakID,
Effect = T.takeError();
}
assert(Effect.hasValue() && "Expected at least one selection");
if (*Effect) {
// Tweaks don't apply clang-format, do that centrally here.
if (*Effect && (*Effect)->FormatEdits) {
// Format tweaks that require it centrally here.
for (auto &It : (*Effect)->ApplyEdits) {
Edit &E = It.second;
format::FormatStyle Style =
Expand Down
3 changes: 3 additions & 0 deletions clang-tools-extra/clangd/refactor/Tweak.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ class Tweak {
/// A message to be displayed to the user.
llvm::Optional<std::string> ShowMessage;
FileEdits ApplyEdits;
/// Whether the edits should be formatted before presenting to the client.
/// Note that it applies to all files.
bool FormatEdits = true;

static Effect showMessage(StringRef S) {
Effect E;
Expand Down
57 changes: 57 additions & 0 deletions clang-tools-extra/clangd/unittests/ClangdTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,22 @@
#include "TestTU.h"
#include "TidyProvider.h"
#include "URI.h"
#include "refactor/Tweak.h"
#include "support/MemoryTree.h"
#include "support/Path.h"
#include "support/Threading.h"
#include "clang/Config/config.h"
#include "clang/Sema/CodeCompleteConsumer.h"
#include "clang/Tooling/ArgumentsAdjusters.h"
#include "clang/Tooling/Core/Replacement.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/VirtualFileSystem.h"
Expand Down Expand Up @@ -1259,6 +1262,60 @@ TEST(ClangdServer, MemoryUsageTest) {
ASSERT_TRUE(MT.children().count("tuscheduler"));
EXPECT_TRUE(MT.child("tuscheduler").children().count(FooCpp));
}

TEST(ClangdServer, RespectsTweakFormatting) {
static constexpr const char *TweakID = "ModuleTweak";
static constexpr const char *NewContents = "{not;\nformatted;}";

// Contributes a tweak that generates a non-formatted insertion and disables
// formatting.
struct TweakContributingModule final : public FeatureModule {
struct ModuleTweak final : public Tweak {
const char *id() const override { return TweakID; }
bool prepare(const Selection &Sel) override { return true; }
Expected<Effect> apply(const Selection &Sel) override {
auto &SM = Sel.AST->getSourceManager();
llvm::StringRef FilePath = SM.getFilename(Sel.Cursor);
tooling::Replacements Reps;
llvm::cantFail(
Reps.add(tooling::Replacement(FilePath, 0, 0, NewContents)));
auto E = llvm::cantFail(Effect::mainFileEdit(SM, std::move(Reps)));
E.FormatEdits = false;
return E;
}
std::string title() const override { return id(); }
llvm::StringLiteral kind() const override {
return llvm::StringLiteral("");
};
};

void contributeTweaks(std::vector<std::unique_ptr<Tweak>> &Out) override {
Out.emplace_back(new ModuleTweak);
}
};

MockFS FS;
MockCompilationDatabase CDB;
auto Opts = ClangdServer::optsForTest();
FeatureModuleSet Set;
Set.add(std::make_unique<TweakContributingModule>());
Opts.FeatureModules = &Set;
ClangdServer Server(CDB, FS, Opts);

auto FooCpp = testPath("foo.cpp");
Server.addDocument(FooCpp, "");
ASSERT_TRUE(Server.blockUntilIdleForTest());

// Ensure that disabled formatting is respected.
Notification N;
Server.applyTweak(FooCpp, {}, TweakID, [&](llvm::Expected<Tweak::Effect> E) {
ASSERT_TRUE(static_cast<bool>(E));
EXPECT_THAT(llvm::cantFail(E->ApplyEdits.lookup(FooCpp).apply()),
NewContents);
N.notify();
});
N.wait();
}
} // namespace
} // namespace clangd
} // namespace clang

0 comments on commit 614b46e

Please sign in to comment.