usaxena95 updated this revision to Diff 455920.
usaxena95 marked 11 inline comments as done.
usaxena95 added a comment.
Addressed comments.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D131154/new/
https://reviews.llvm.org/D131154
Files:
clang-tools-extra/clangd/ClangdLSPServer.cpp
clang-tools-extra/clangd/ClangdServer.cpp
clang-tools-extra/clangd/ClangdServer.h
clang-tools-extra/clangd/Protocol.cpp
clang-tools-extra/clangd/Protocol.h
clang-tools-extra/clangd/SemanticSelection.cpp
clang-tools-extra/clangd/SemanticSelection.h
clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp
Index: clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp
+++ clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp
@@ -196,7 +196,7 @@
ElementsAre(SourceAnnotations.range("empty")));
}
-TEST(FoldingRanges, All) {
+TEST(FoldingRanges, ASTAll) {
const char *Tests[] = {
R"cpp(
#define FOO int foo() {\
@@ -265,7 +265,7 @@
}
}
-TEST(FoldingRangesPseudoParser, All) {
+TEST(FoldingRanges, PseudoParserWithoutLineFoldings) {
const char *Tests[] = {
R"cpp(
#define FOO int foo() {\
@@ -359,13 +359,67 @@
};
for (const char *Test : Tests) {
auto T = Annotations(Test);
- EXPECT_THAT(
- gatherFoldingRanges(llvm::cantFail(getFoldingRanges(T.code().str()))),
- UnorderedElementsAreArray(T.ranges()))
+ EXPECT_THAT(gatherFoldingRanges(llvm::cantFail(getFoldingRanges(
+ T.code().str(), /*LineFoldingsOnly=*/false))),
+ UnorderedElementsAreArray(T.ranges()))
<< Test;
}
}
+TEST(FoldingRanges, PseudoParserLineFoldingsOnly) {
+ const char *Tests[] = {
+ R"cpp(
+ void func(int a) {[[
+ a++;]]
+ }
+ )cpp",
+ R"cpp(
+ // Always exclude last line for brackets.
+ void func(int a) {[[
+ if(a == 1) {[[
+ a++;]]
+ } else if (a == 2){[[
+ a--;]]
+ } else { // No folding for 2 line bracketed ranges.
+ }]]
+ }
+ )cpp",
+ R"cpp(
+ [[/* comment
+ * comment]]
+ */
+
+ /* No folding for this comment.
+ */
+
+ // No folding for this comment.
+
+ [[// 2 single line comment.
+ // 2 single line comment.]]
+
+ [[// >=2 line comments.
+ // >=2 line comments.
+ // >=2 line comments.]]
+ )cpp",
+
+ };
+ auto StripColumns = [](const std::vector<Range> &Ranges) {
+ std::vector<Range> Res;
+ for (Range R : Ranges) {
+ R.start.character = R.end.character = 0;
+ Res.push_back(R);
+ }
+ return Res;
+ };
+ for (const char *Test : Tests) {
+ auto T = Annotations(Test);
+ EXPECT_THAT(
+ StripColumns(gatherFoldingRanges(llvm::cantFail(
+ getFoldingRanges(T.code().str(), /*LineFoldingsOnly=*/true)))),
+ UnorderedElementsAreArray(StripColumns(T.ranges())))
+ << Test;
+ }
+}
} // namespace
} // namespace clangd
} // namespace clang
Index: clang-tools-extra/clangd/SemanticSelection.h
===================================================================
--- clang-tools-extra/clangd/SemanticSelection.h
+++ clang-tools-extra/clangd/SemanticSelection.h
@@ -33,7 +33,7 @@
/// Returns a list of ranges whose contents might be collapsible in an editor.
/// This version uses the pseudoparser which does not require the AST.
llvm::Expected<std::vector<FoldingRange>>
-getFoldingRanges(const std::string &Code);
+getFoldingRanges(const std::string &Code, bool LineFoldingOnly);
} // namespace clangd
} // namespace clang
Index: clang-tools-extra/clangd/SemanticSelection.cpp
===================================================================
--- clang-tools-extra/clangd/SemanticSelection.cpp
+++ clang-tools-extra/clangd/SemanticSelection.cpp
@@ -179,7 +179,7 @@
// statement bodies).
// Related issue: https://github.com/clangd/clangd/issues/310
llvm::Expected<std::vector<FoldingRange>>
-getFoldingRanges(const std::string &Code) {
+getFoldingRanges(const std::string &Code, bool LineFoldingOnly) {
auto OrigStream = pseudo::lex(Code, clang::pseudo::genericLangOpts());
auto DirectiveStructure = pseudo::DirectiveTree::parse(OrigStream);
@@ -192,15 +192,17 @@
pseudo::pairBrackets(ParseableStream);
std::vector<FoldingRange> Result;
- auto ToFoldingRange = [](Position Start, Position End,
- llvm::StringLiteral Kind) {
+ auto AddFoldingRange = [&](Position Start, Position End,
+ llvm::StringLiteral Kind) {
+ if (Start.line >= End.line)
+ return;
FoldingRange FR;
FR.startLine = Start.line;
- FR.startCharacter = Start.character;
FR.endLine = End.line;
+ FR.startCharacter = Start.character;
FR.endCharacter = End.character;
FR.kind = Kind.str();
- return FR;
+ Result.push_back(FR);
};
auto OriginalToken = [&](const pseudo::Token &T) {
return OrigStream.tokens()[T.OriginalIndex];
@@ -223,26 +225,34 @@
if (Tok.Line < Paired->Line) {
Position Start = offsetToPosition(Code, 1 + StartOffset(Tok));
Position End = StartPosition(*Paired);
- Result.push_back(ToFoldingRange(Start, End, FoldingRange::REGION_KIND));
+ if (LineFoldingOnly)
+ End.line--;
+ AddFoldingRange(Start, End, FoldingRange::REGION_KIND);
}
}
}
// Multi-line comments.
- for (const auto *T = Tokens.begin(); T != Tokens.end();) {
+ for (auto *T = Tokens.begin(); T != Tokens.end();) {
if (T->Kind != tok::comment) {
T++;
continue;
}
Position Start = StartPosition(*T);
- Position LastCommentEnd = EndPosition(*T);
+ pseudo::Token *LastComment = T;
+ Position End = EndPosition(*T);
while (T != Tokens.end() && T->Kind == tok::comment &&
- StartPosition(*T).line <= LastCommentEnd.line + 1) {
- LastCommentEnd = EndPosition(*T);
+ StartPosition(*T).line <= End.line + 1) {
+ End = EndPosition(*T);
+ LastComment = T;
T++;
}
- if (Start.line < LastCommentEnd.line)
- Result.push_back(
- ToFoldingRange(Start, LastCommentEnd, FoldingRange::COMMENT_KIND));
+ if (LineFoldingOnly) {
+ // Always show last line of a block comment.
+ if (StartPosition(*LastComment).line != EndPosition(*LastComment).line) {
+ End.line--;
+ }
+ }
+ AddFoldingRange(Start, End, FoldingRange::COMMENT_KIND);
}
return Result;
}
Index: clang-tools-extra/clangd/Protocol.h
===================================================================
--- clang-tools-extra/clangd/Protocol.h
+++ clang-tools-extra/clangd/Protocol.h
@@ -437,6 +437,12 @@
/// textDocument.signatureHelp
bool HasSignatureHelp = false;
+ /// Client signals that it only supports folding complete lines.
+ /// Client will ignore specified `startCharacter` and `endCharacter`
+ /// properties in a FoldingRange.
+ /// textDocument.foldingRange.lineFoldingOnly
+ bool LineFoldingOnly = false;
+
/// Client supports processing label offsets instead of a simple label string.
/// textDocument.signatureHelp.signatureInformation.parameterInformation.labelOffsetSupport
bool OffsetsInSignatureHelp = false;
Index: clang-tools-extra/clangd/Protocol.cpp
===================================================================
--- clang-tools-extra/clangd/Protocol.cpp
+++ clang-tools-extra/clangd/Protocol.cpp
@@ -391,6 +391,10 @@
}
}
}
+ if (auto *Folding = TextDocument->getObject("foldingRange")) {
+ if (auto LineFolding = Folding->getBoolean("lineFoldingOnly"))
+ R.LineFoldingOnly = *LineFolding;
+ }
if (auto *Rename = TextDocument->getObject("rename")) {
if (auto RenameSupport = Rename->getBoolean("prepareSupport"))
R.RenamePrepareSupport = *RenameSupport;
Index: clang-tools-extra/clangd/ClangdServer.h
===================================================================
--- clang-tools-extra/clangd/ClangdServer.h
+++ clang-tools-extra/clangd/ClangdServer.h
@@ -164,6 +164,9 @@
/// Enable preview of FoldingRanges feature.
bool FoldingRanges = false;
+ // Whether the client supports folding only complete lines.
+ bool LineFoldingOnly = false;
+
FeatureModuleSet *FeatureModules = nullptr;
/// If true, use the dirty buffer contents when building Preambles.
bool UseDirtyHeaders = false;
@@ -429,6 +432,9 @@
bool UseDirtyHeaders = false;
+ // Whether the client supports folding only complete lines.
+ bool LineFoldingOnly = false;
+
bool PreambleParseForwardingFunctions = false;
// GUARDED_BY(CachedCompletionFuzzyFindRequestMutex)
Index: clang-tools-extra/clangd/ClangdServer.cpp
===================================================================
--- clang-tools-extra/clangd/ClangdServer.cpp
+++ clang-tools-extra/clangd/ClangdServer.cpp
@@ -177,6 +177,7 @@
DynamicIdx(Opts.BuildDynamicSymbolIndex ? new FileIndex() : nullptr),
ClangTidyProvider(Opts.ClangTidyProvider),
UseDirtyHeaders(Opts.UseDirtyHeaders),
+ LineFoldingOnly(Opts.LineFoldingOnly),
PreambleParseForwardingFunctions(Opts.PreambleParseForwardingFunctions),
WorkspaceRoot(Opts.WorkspaceRoot),
Transient(Opts.ImplicitCancellation ? TUScheduler::InvalidateOnUpdate
@@ -855,8 +856,9 @@
return CB(llvm::make_error<LSPError>(
"trying to compute folding ranges for non-added document",
ErrorCode::InvalidParams));
- auto Action = [CB = std::move(CB), Code = std::move(*Code)]() mutable {
- CB(clangd::getFoldingRanges(Code));
+ auto Action = [LineFoldingOnly = LineFoldingOnly, CB = std::move(CB),
+ Code = std::move(*Code)]() mutable {
+ CB(clangd::getFoldingRanges(Code, LineFoldingOnly));
};
// We want to make sure folding ranges are always available for all the open
// files, hence prefer runQuick to not wait for operations on other files.
Index: clang-tools-extra/clangd/ClangdLSPServer.cpp
===================================================================
--- clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -514,6 +514,7 @@
Params.capabilities.HierarchicalDocumentSymbol;
SupportFileStatus = Params.initializationOptions.FileStatus;
HoverContentFormat = Params.capabilities.HoverContentFormat;
+ Opts.LineFoldingOnly = Params.capabilities.LineFoldingOnly;
SupportsOffsetsInSignatureHelp = Params.capabilities.OffsetsInSignatureHelp;
if (Params.capabilities.WorkDoneProgress)
BackgroundIndexProgressState = BackgroundIndexProgress::Empty;
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits