summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang-tools-extra/clangd/ClangdServer.cpp6
-rw-r--r--clang-tools-extra/clangd/ClangdUnit.cpp3
-rw-r--r--clang-tools-extra/clangd/Compiler.h2
-rw-r--r--clang-tools-extra/clangd/SourceCode.cpp9
-rw-r--r--clang-tools-extra/clangd/SourceCode.h5
-rw-r--r--clang-tools-extra/clangd/refactor/Tweak.cpp8
-rw-r--r--clang-tools-extra/clangd/refactor/Tweak.h14
-rw-r--r--clang-tools-extra/clangd/refactor/tweaks/SwapIfBranches.cpp7
-rw-r--r--clang-tools-extra/unittests/clangd/TweakTests.cpp40
9 files changed, 81 insertions, 13 deletions
diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp
index 2dcf0fb36fb..1aa87998181 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -152,6 +152,9 @@ void ClangdServer::addDocument(PathRef File, llvm::StringRef Contents,
Opts.ClangTidyOpts = tidy::ClangTidyOptions::getDefaults();
if (ClangTidyOptProvider)
Opts.ClangTidyOpts = ClangTidyOptProvider->getOptions(File);
+ // FIXME: cache this.
+ Opts.Style =
+ getFormatStyleForFile(File, Contents, FSProvider.getFileSystem().get());
Opts.SuggestMissingIncludes = SuggestMissingIncludes;
// FIXME: some build systems like Bazel will take time to preparing
// environment to build the file, it would be nice if we could emit a
@@ -372,8 +375,7 @@ void ClangdServer::applyTweak(PathRef File, Range Sel, StringRef TweakID,
auto A = prepareTweak(TweakID, *Selection);
if (!A)
return CB(A.takeError());
- // FIXME: run formatter on top of resulting replacements.
- return CB((*A)->apply(*Selection));
+ return CB((*A)->apply(*Selection, InpAST->Inputs.Opts.Style));
};
WorkScheduler.runWithAST(
"ApplyTweak", File,
diff --git a/clang-tools-extra/clangd/ClangdUnit.cpp b/clang-tools-extra/clangd/ClangdUnit.cpp
index ffb96fbf6d2..cb7fae5ff30 100644
--- a/clang-tools-extra/clangd/ClangdUnit.cpp
+++ b/clang-tools-extra/clangd/ClangdUnit.cpp
@@ -309,9 +309,8 @@ ParsedAST::build(std::unique_ptr<CompilerInvocation> CI,
llvm::Optional<IncludeFixer> FixIncludes;
auto BuildDir = VFS->getCurrentWorkingDirectory();
if (Opts.SuggestMissingIncludes && Index && !BuildDir.getError()) {
- auto Style = getFormatStyleForFile(MainInput.getFile(), Content, VFS.get());
auto Inserter = std::make_shared<IncludeInserter>(
- MainInput.getFile(), Content, Style, BuildDir.get(),
+ MainInput.getFile(), Content, Opts.Style, BuildDir.get(),
Clang->getPreprocessor().getHeaderSearchInfo());
if (Preamble) {
for (const auto &Inc : Preamble->Includes.MainFileIncludes)
diff --git a/clang-tools-extra/clangd/Compiler.h b/clang-tools-extra/clangd/Compiler.h
index 9466d8e2c08..2d5c1b3e44a 100644
--- a/clang-tools-extra/clangd/Compiler.h
+++ b/clang-tools-extra/clangd/Compiler.h
@@ -17,6 +17,7 @@
#include "../clang-tidy/ClangTidyOptions.h"
#include "index/Index.h"
+#include "clang/Format/Format.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/PrecompiledPreamble.h"
@@ -38,6 +39,7 @@ public:
struct ParseOptions {
tidy::ClangTidyOptions ClangTidyOpts;
bool SuggestMissingIncludes = false;
+ format::FormatStyle Style;
};
/// Information required to run clang, e.g. to parse AST or do code completion.
diff --git a/clang-tools-extra/clangd/SourceCode.cpp b/clang-tools-extra/clangd/SourceCode.cpp
index a4af1a9d735..86146758a54 100644
--- a/clang-tools-extra/clangd/SourceCode.cpp
+++ b/clang-tools-extra/clangd/SourceCode.cpp
@@ -335,5 +335,14 @@ format::FormatStyle getFormatStyleForFile(llvm::StringRef File,
return *Style;
}
+llvm::Expected<tooling::Replacements>
+cleanupAndFormat(StringRef Code, const tooling::Replacements &Replaces,
+ const format::FormatStyle &Style) {
+ auto CleanReplaces = cleanupAroundReplacements(Code, Replaces, Style);
+ if (!CleanReplaces)
+ return CleanReplaces;
+ return formatReplacements(Code, std::move(*CleanReplaces), Style);
+}
+
} // namespace clangd
} // namespace clang
diff --git a/clang-tools-extra/clangd/SourceCode.h b/clang-tools-extra/clangd/SourceCode.h
index 37b7b166a81..e6ce8c3be5d 100644
--- a/clang-tools-extra/clangd/SourceCode.h
+++ b/clang-tools-extra/clangd/SourceCode.h
@@ -144,6 +144,11 @@ format::FormatStyle getFormatStyleForFile(llvm::StringRef File,
llvm::StringRef Content,
llvm::vfs::FileSystem *FS);
+// Cleanup and format the given replacements.
+llvm::Expected<tooling::Replacements>
+cleanupAndFormat(StringRef Code, const tooling::Replacements &Replaces,
+ const format::FormatStyle &Style);
+
} // namespace clangd
} // namespace clang
#endif
diff --git a/clang-tools-extra/clangd/refactor/Tweak.cpp b/clang-tools-extra/clangd/refactor/Tweak.cpp
index 34634e64b6f..6a3b090b80b 100644
--- a/clang-tools-extra/clangd/refactor/Tweak.cpp
+++ b/clang-tools-extra/clangd/refactor/Tweak.cpp
@@ -46,6 +46,14 @@ Tweak::Selection::Selection(ParsedAST &AST, unsigned RangeBegin,
Cursor = SM.getComposedLoc(SM.getMainFileID(), RangeBegin);
}
+Expected<tooling::Replacements> Tweak::apply(const Selection &Sel,
+ const format::FormatStyle &Style) {
+ auto RawReplacements = execute(Sel);
+ if (!RawReplacements)
+ return RawReplacements;
+ return cleanupAndFormat(Sel.Code, *RawReplacements, Style);
+}
+
std::vector<std::unique_ptr<Tweak>> prepareTweaks(const Tweak::Selection &S) {
validateRegistry();
diff --git a/clang-tools-extra/clangd/refactor/Tweak.h b/clang-tools-extra/clangd/refactor/Tweak.h
index 35c3ce8a93c..108e07e1b01 100644
--- a/clang-tools-extra/clangd/refactor/Tweak.h
+++ b/clang-tools-extra/clangd/refactor/Tweak.h
@@ -22,6 +22,7 @@
#include "ClangdUnit.h"
#include "Protocol.h"
#include "Selection.h"
+#include "clang/Format/Format.h"
#include "clang/Tooling/Core/Replacement.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
@@ -47,7 +48,7 @@ public:
ParsedAST &AST;
/// A location of the cursor in the editor.
SourceLocation Cursor;
- // The AST nodes that were selected.
+ /// The AST nodes that were selected.
SelectionTree ASTSelection;
// FIXME: provide a way to get sources and ASTs for other files.
};
@@ -63,13 +64,20 @@ public:
/// should be moved into 'apply'.
/// Returns true iff the action is available and apply() can be called on it.
virtual bool prepare(const Selection &Sel) = 0;
- /// Run the second stage of the action that would produce the actual changes.
+ /// Format and apply the actual changes generated from the second stage of the
+ /// action.
/// EXPECTS: prepare() was called and returned true.
- virtual Expected<tooling::Replacements> apply(const Selection &Sel) = 0;
+ Expected<tooling::Replacements> apply(const Selection &Sel,
+ const format::FormatStyle &Style);
/// A one-line title of the action that should be shown to the users in the
/// UI.
/// EXPECTS: prepare() was called and returned true.
virtual std::string title() const = 0;
+
+protected:
+ /// Run the second stage of the action that would produce the actual changes.
+ /// EXPECTS: prepare() was called and returned true.
+ virtual Expected<tooling::Replacements> execute(const Selection &Sel) = 0;
};
// All tweaks must be registered in the .cpp file next to their definition.
diff --git a/clang-tools-extra/clangd/refactor/tweaks/SwapIfBranches.cpp b/clang-tools-extra/clangd/refactor/tweaks/SwapIfBranches.cpp
index 9b0b72d94ca..40dd6987150 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/SwapIfBranches.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/SwapIfBranches.cpp
@@ -37,9 +37,11 @@ public:
const char *id() const override final;
bool prepare(const Selection &Inputs) override;
- Expected<tooling::Replacements> apply(const Selection &Inputs) override;
std::string title() const override;
+protected:
+ Expected<tooling::Replacements> execute(const Selection &Inputs) override;
+
private:
const IfStmt *If = nullptr;
};
@@ -60,7 +62,8 @@ bool SwapIfBranches::prepare(const Selection &Inputs) {
dyn_cast_or_null<CompoundStmt>(If->getElse());
}
-Expected<tooling::Replacements> SwapIfBranches::apply(const Selection &Inputs) {
+Expected<tooling::Replacements>
+SwapIfBranches::execute(const Selection &Inputs) {
auto &Ctx = Inputs.AST.getASTContext();
auto &SrcMgr = Ctx.getSourceManager();
diff --git a/clang-tools-extra/unittests/clangd/TweakTests.cpp b/clang-tools-extra/unittests/clangd/TweakTests.cpp
index baa60292e3d..a76d3aea800 100644
--- a/clang-tools-extra/unittests/clangd/TweakTests.cpp
+++ b/clang-tools-extra/unittests/clangd/TweakTests.cpp
@@ -98,7 +98,7 @@ llvm::Expected<std::string> apply(StringRef ID, llvm::StringRef Input) {
auto T = prepareTweak(ID, S);
if (!T)
return T.takeError();
- auto Replacements = (*T)->apply(S);
+ auto Replacements = (*T)->apply(S, clang::format::getLLVMStyle());
if (!Replacements)
return Replacements.takeError();
return applyAllReplacements(Code.code(), *Replacements);
@@ -127,12 +127,40 @@ TEST(TweakTest, SwapIfBranches) {
llvm::StringLiteral Input = R"cpp(
void test() {
- ^if (true) { return 100; } else { continue; }
+ ^if (true) {
+ return 100;
+ } else {
+ continue;
+ }
}
)cpp";
llvm::StringLiteral Output = R"cpp(
void test() {
- if (true) { continue; } else { return 100; }
+ if (true) {
+ continue;
+ } else {
+ return 100;
+ }
+ }
+ )cpp";
+ checkTransform(ID, Input, Output);
+
+ Input = R"cpp(
+ void test() {
+ ^if () {
+ return 100;
+ } else {
+ continue;
+ }
+ }
+ )cpp";
+ Output = R"cpp(
+ void test() {
+ if () {
+ continue;
+ } else {
+ return 100;
+ }
}
)cpp";
checkTransform(ID, Input, Output);
@@ -144,7 +172,11 @@ TEST(TweakTest, SwapIfBranches) {
)cpp";
Output = R"cpp(
void test() {
- if () { continue; } else { return 100; }
+ if () {
+ continue;
+ } else {
+ return 100;
+ }
}
)cpp";
checkTransform(ID, Input, Output);
OpenPOWER on IntegriCloud