[clang-tools-extra] 9ef1161 - Add foldings for multi-line comment.
Utkarsh Saxena via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 2 23:19:21 PDT 2022
Author: Utkarsh Saxena
Date: 2022-08-03T08:19:12+02:00
New Revision: 9ef11616b228fc2f69cd8fe7f7fd3e821d74c182
URL: https://github.com/llvm/llvm-project/commit/9ef11616b228fc2f69cd8fe7f7fd3e821d74c182
DIFF: https://github.com/llvm/llvm-project/commit/9ef11616b228fc2f69cd8fe7f7fd3e821d74c182.diff
LOG: Add foldings for multi-line comment.
Differential Revision: https://reviews.llvm.org/D130081
Added:
Modified:
clang-tools-extra/clangd/Protocol.cpp
clang-tools-extra/clangd/Protocol.h
clang-tools-extra/clangd/SemanticSelection.cpp
clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp
index 622f527f75f4f..979da9b2b99d3 100644
--- a/clang-tools-extra/clangd/Protocol.cpp
+++ b/clang-tools-extra/clangd/Protocol.cpp
@@ -1443,6 +1443,10 @@ bool fromJSON(const llvm::json::Value &Params, FoldingRangeParams &R,
return O && O.map("textDocument", R.textDocument);
}
+const llvm::StringLiteral FoldingRange::REGION_KIND = "region";
+const llvm::StringLiteral FoldingRange::COMMENT_KIND = "comment";
+const llvm::StringLiteral FoldingRange::IMPORT_KIND = "import";
+
llvm::json::Value toJSON(const FoldingRange &Range) {
llvm::json::Object Result{
{"startLine", Range.startLine},
diff --git a/clang-tools-extra/clangd/Protocol.h b/clang-tools-extra/clangd/Protocol.h
index add24daa1bc6d..648c7bd872519 100644
--- a/clang-tools-extra/clangd/Protocol.h
+++ b/clang-tools-extra/clangd/Protocol.h
@@ -1776,6 +1776,10 @@ struct FoldingRange {
unsigned startCharacter;
unsigned endLine = 0;
unsigned endCharacter;
+
+ const static llvm::StringLiteral REGION_KIND;
+ const static llvm::StringLiteral COMMENT_KIND;
+ const static llvm::StringLiteral IMPORT_KIND;
std::string kind;
};
llvm::json::Value toJSON(const FoldingRange &Range);
diff --git a/clang-tools-extra/clangd/SemanticSelection.cpp b/clang-tools-extra/clangd/SemanticSelection.cpp
index affac26fec912..b82df8ebc2595 100644
--- a/clang-tools-extra/clangd/SemanticSelection.cpp
+++ b/clang-tools-extra/clangd/SemanticSelection.cpp
@@ -22,6 +22,7 @@
#include "clang/Tooling/Syntax/TokenBufferTokenManager.h"
#include "clang/Tooling/Syntax/Tree.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Error.h"
#include <queue>
@@ -173,16 +174,16 @@ llvm::Expected<std::vector<FoldingRange>> getFoldingRanges(ParsedAST &AST) {
return collectFoldingRanges(SyntaxTree, TM);
}
-// FIXME(kirillbobyrev): Collect comments, PP conditional regions, includes and
-// other code regions (e.g. public/private/protected sections of classes,
-// control flow statement bodies).
+// FIXME( usaxena95): Collect PP conditional regions, includes and other code
+// regions (e.g. public/private/protected sections of classes, control flow
+// statement bodies).
// Related issue: https://github.com/clangd/clangd/issues/310
llvm::Expected<std::vector<FoldingRange>>
getFoldingRanges(const std::string &Code) {
- auto OrigStream = clang::pseudo::lex(Code, clang::pseudo::genericLangOpts());
+ auto OrigStream = pseudo::lex(Code, clang::pseudo::genericLangOpts());
- auto DirectiveStructure = clang::pseudo::DirectiveTree::parse(OrigStream);
- clang::pseudo::chooseConditionalBranches(DirectiveStructure, OrigStream);
+ auto DirectiveStructure = pseudo::DirectiveTree::parse(OrigStream);
+ pseudo::chooseConditionalBranches(DirectiveStructure, OrigStream);
// FIXME: Provide ranges in the disabled-PP regions as well.
auto Preprocessed = DirectiveStructure.stripDirectives(OrigStream);
@@ -191,26 +192,58 @@ getFoldingRanges(const std::string &Code) {
pseudo::pairBrackets(ParseableStream);
std::vector<FoldingRange> Result;
- for (const auto &Tok : ParseableStream.tokens()) {
+ auto ToFoldingRange = [](Position Start, Position End,
+ llvm::StringLiteral Kind) {
+ FoldingRange FR;
+ FR.startLine = Start.line;
+ FR.startCharacter = Start.character;
+ FR.endLine = End.line;
+ FR.endCharacter = End.character;
+ FR.kind = Kind.str();
+ return FR;
+ };
+ auto OriginalToken = [&](const pseudo::Token &T) {
+ return OrigStream.tokens()[T.OriginalIndex];
+ };
+ auto StartOffset = [&](const pseudo::Token &T) {
+ return OriginalToken(T).text().data() - Code.data();
+ };
+ auto StartPosition = [&](const pseudo::Token &T) {
+ return offsetToPosition(Code, StartOffset(T));
+ };
+ auto EndPosition = [&](const pseudo::Token &T) {
+ return offsetToPosition(Code, StartOffset(T) + OriginalToken(T).Length);
+ };
+ auto Tokens = ParseableStream.tokens();
+ // Brackets.
+ for (const auto &Tok : Tokens) {
if (auto *Paired = Tok.pair()) {
// Process only token at the start of the range. Avoid ranges on a single
// line.
if (Tok.Line < Paired->Line) {
- Position Start = offsetToPosition(
- Code,
- OrigStream.tokens()[Tok.OriginalIndex].text().data() - Code.data());
- Position End = offsetToPosition(
- Code, OrigStream.tokens()[Paired->OriginalIndex].text().data() -
- Code.data());
- FoldingRange FR;
- FR.startLine = Start.line;
- FR.startCharacter = Start.character + 1;
- FR.endLine = End.line;
- FR.endCharacter = End.character;
- Result.push_back(FR);
+ Position Start = offsetToPosition(Code, 1 + StartOffset(Tok));
+ Position End = StartPosition(*Paired);
+ Result.push_back(ToFoldingRange(Start, End, FoldingRange::REGION_KIND));
}
}
}
+ // Multi-line comments.
+ for (const auto *T = Tokens.begin(); T != Tokens.end();) {
+ if (T->Kind != tok::comment) {
+ T++;
+ continue;
+ }
+ Position Start = StartPosition(*T);
+ Position LastCommentEnd = EndPosition(*T);
+ while (T != Tokens.end() && T->Kind == tok::comment &&
+ StartPosition(*T).line <= LastCommentEnd.line + 1) {
+ LastCommentEnd = EndPosition(*T);
+ T++;
+ }
+ if (Start.line < LastCommentEnd.line)
+ Result.push_back(
+ ToFoldingRange(Start, LastCommentEnd, FoldingRange::COMMENT_KIND));
+ }
return Result;
}
diff --git a/clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp b/clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp
index a41553097fdfc..de2960869b1e9 100644
--- a/clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp
@@ -335,6 +335,27 @@ TEST(FoldingRangesPseudoParser, All) {
]]} \
]]};
)cpp",
+ R"cpp(
+ [[/* Multi
+ * line
+ * comment
+ */]]
+ )cpp",
+ R"cpp(
+ [[// Comment
+ // 1]]
+
+ [[// Comment
+ // 2]]
+
+ // No folding for single line comment.
+
+ [[/* comment 3
+ */]]
+
+ [[/* comment 4
+ */]]
+ )cpp",
};
for (const char *Test : Tests) {
auto T = Annotations(Test);
More information about the cfe-commits
mailing list