hokein created this revision.
hokein added a reviewer: ilya-biryukov.
Herald added subscribers: kadircet, arphaman, jkorous, MaskRay, ioeric.
Herald added a project: clang.
Repository:
rCTE Clang Tools Extra
https://reviews.llvm.org/D57739
Files:
clangd/ClangdLSPServer.cpp
clangd/ClangdServer.cpp
clangd/ClangdServer.h
clangd/Format.h
unittests/clangd/TweakTests.cpp
Index: unittests/clangd/TweakTests.cpp
===================================================================
--- unittests/clangd/TweakTests.cpp
+++ unittests/clangd/TweakTests.cpp
@@ -9,6 +9,7 @@
#include "Annotations.h"
#include "SourceCode.h"
+#include "Format.h"
#include "TestTU.h"
#include "refactor/Tweak.h"
#include "clang/AST/Expr.h"
@@ -77,7 +78,8 @@
void checkNotAvailable(StringRef ID, llvm::StringRef Input) {
return checkAvailable(ID, Input, /*Available=*/false);
}
-llvm::Expected<std::string> apply(StringRef ID, llvm::StringRef Input) {
+llvm::Expected<std::string> apply(StringRef ID, llvm::StringRef Input,
+ bool Format) {
Annotations Code(Input);
Range SelectionRng;
if (Code.points().size() != 0) {
@@ -102,12 +104,19 @@
auto Replacements = (*T)->apply(S);
if (!Replacements)
return Replacements.takeError();
+ if (Format) {
+ Replacements = cleanupAndFormat(
+ Code.code(), *Replacements,
+ clang::format::getGoogleStyle(::clang::format::FormatStyle::LK_Cpp));
+ if (!Replacements)
+ return Replacements.takeError();
+ }
return applyAllReplacements(Code.code(), *Replacements);
}
void checkTransform(llvm::StringRef ID, llvm::StringRef Input,
- llvm::StringRef Output) {
- EXPECT_THAT_EXPECTED(apply(ID, Input), HasValue(Output))
+ llvm::StringRef Output, bool Format = false) {
+ EXPECT_THAT_EXPECTED(apply(ID, Input, Format), HasValue(Output))
<< "action id is" << ID;
}
@@ -150,6 +159,22 @@
)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, /*Format=*/true);
+
// Available in subexpressions of the condition.
checkAvailable(ID, R"cpp(
void test() {
Index: clangd/Format.h
===================================================================
--- /dev/null
+++ clangd/Format.h
@@ -0,0 +1,28 @@
+//===--- Format.h ------------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Format/Format.h"
+#include "clang/Tooling/Core/Replacement.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+
+namespace clang {
+namespace clangd {
+
+// Cleanup and format the given replacements.
+inline 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
\ No newline at end of file
Index: clangd/ClangdServer.h
===================================================================
--- clangd/ClangdServer.h
+++ clangd/ClangdServer.h
@@ -23,6 +23,7 @@
#include "index/FileIndex.h"
#include "index/Index.h"
#include "refactor/Tweak.h"
+#include "clang/Format/Format.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/Core/Replacement.h"
#include "llvm/ADT/FunctionExtras.h"
@@ -223,7 +224,7 @@
Callback<std::vector<TweakRef>> CB);
/// Apply the code tweak with a specified \p ID.
- void applyTweak(PathRef File, Range Sel, StringRef ID,
+ void applyTweak(StringRef Code, PathRef File, Range Sel, StringRef ID,
Callback<tooling::Replacements> CB);
/// Only for testing purposes.
@@ -257,12 +258,15 @@
blockUntilIdleForTest(llvm::Optional<double> TimeoutSeconds = 10);
private:
- /// FIXME: This stats several files to find a .clang-format file. I/O can be
- /// slow. Think of a way to cache this.
llvm::Expected<tooling::Replacements>
formatCode(llvm::StringRef Code, PathRef File,
ArrayRef<tooling::Range> Ranges);
+ /// FIXME: This stats several files to find a .clang-format file. I/O can be
+ /// slow. Think of a way to cache this.
+ llvm::Expected<format::FormatStyle> getFormatStyle(llvm::StringRef Code,
+ PathRef File);
+
tooling::CompileCommand getCompileCommand(PathRef File);
const GlobalCompilationDatabase &CDB;
Index: clangd/ClangdServer.cpp
===================================================================
--- clangd/ClangdServer.cpp
+++ clangd/ClangdServer.cpp
@@ -10,6 +10,7 @@
#include "ClangdUnit.h"
#include "CodeComplete.h"
#include "FindSymbols.h"
+#include "Format.h"
#include "Headers.h"
#include "SourceCode.h"
#include "Trace.h"
@@ -358,9 +359,14 @@
Bind(Action, std::move(CB), File.str()));
}
-void ClangdServer::applyTweak(PathRef File, Range Sel, StringRef TweakID,
+void ClangdServer::applyTweak(StringRef Code, PathRef File, Range Sel,
+ StringRef TweakID,
Callback<tooling::Replacements> CB) {
+ auto Style = getFormatStyle(Code, File);
+ if (!Style)
+ return;
auto Action = [Sel](decltype(CB) CB, std::string File, std::string TweakID,
+ format::FormatStyle Style,
Expected<InputsAndAST> InpAST) {
if (!InpAST)
return CB(InpAST.takeError());
@@ -370,12 +376,15 @@
auto A = prepareTweak(TweakID, *Selection);
if (!A)
return CB(A.takeError());
- // FIXME: run formatter on top of resulting replacements.
- return CB((*A)->apply(*Selection));
+ auto ResultReplacements = (*A)->apply(*Selection);
+ if (!ResultReplacements)
+ return CB(ResultReplacements.takeError());
+ return CB(
+ cleanupAndFormat(InpAST->Inputs.Contents, *ResultReplacements, Style));
};
WorkScheduler.runWithAST(
"ApplyTweak", File,
- Bind(Action, std::move(CB), File.str(), TweakID.str()));
+ Bind(Action, std::move(CB), File.str(), TweakID.str(), *Style));
}
void ClangdServer::dumpAST(PathRef File,
@@ -471,9 +480,7 @@
ClangdServer::formatCode(llvm::StringRef Code, PathRef File,
llvm::ArrayRef<tooling::Range> Ranges) {
// Call clang-format.
- auto FS = FSProvider.getFileSystem();
- auto Style = format::getStyle(format::DefaultFormatStyle, File,
- format::DefaultFallbackStyle, Code, FS.get());
+ auto Style = getFormatStyle(Code, File);
if (!Style)
return Style.takeError();
@@ -489,6 +496,13 @@
File));
}
+llvm::Expected<format::FormatStyle>
+ClangdServer::getFormatStyle(llvm::StringRef Code, PathRef File) {
+ return format::getStyle(format::DefaultFormatStyle, File,
+ format::DefaultFallbackStyle, Code,
+ FSProvider.getFileSystem().get());
+}
+
void ClangdServer::findDocumentHighlights(
PathRef File, Position Pos, Callback<std::vector<DocumentHighlight>> CB) {
auto Action = [Pos](Callback<std::vector<DocumentHighlight>> CB,
Index: clangd/ClangdLSPServer.cpp
===================================================================
--- clangd/ClangdLSPServer.cpp
+++ clangd/ClangdLSPServer.cpp
@@ -469,10 +469,10 @@
Reply("Fix applied.");
ApplyEdit(std::move(WE));
};
- Server->applyTweak(Params.tweakArgs->file.file(),
- Params.tweakArgs->selection, Params.tweakArgs->tweakID,
- Bind(Action, std::move(Reply), Params.tweakArgs->file,
- std::move(*Code)));
+ Server->applyTweak(
+ *Code, Params.tweakArgs->file.file(), Params.tweakArgs->selection,
+ Params.tweakArgs->tweakID,
+ Bind(Action, std::move(Reply), Params.tweakArgs->file, *Code));
} else {
// We should not get here because ExecuteCommandParams would not have
// parsed in the first place and this handler should not be called. But if
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits