usaxena95 created this revision. Herald added subscribers: kadircet, arphaman, mgorny. Herald added a project: All. usaxena95 requested review of this revision. Herald added a project: clang-tools-extra. Herald added a subscriber: cfe-commits.
For sharing. WIP Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D129648 Files: clang-tools-extra/clangd/CMakeLists.txt clang-tools-extra/clangd/SemanticSelection.cpp clang-tools-extra/clangd/SemanticSelection.h clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp clang-tools-extra/pseudo/include/clang-pseudo/Token.h clang-tools-extra/pseudo/lib/Lex.cpp
Index: clang-tools-extra/pseudo/lib/Lex.cpp =================================================================== --- clang-tools-extra/pseudo/lib/Lex.cpp +++ clang-tools-extra/pseudo/lib/Lex.cpp @@ -27,6 +27,7 @@ TokenStream Result; clang::Token CT; unsigned LastOffset = 0; + unsigned LineStartOffset = 0; unsigned Line = 0; unsigned Indent = 0; for (Lexer.LexFromRawLexer(CT); CT.getKind() != clang::tok::eof; @@ -40,16 +41,17 @@ Tok.Kind = CT.getKind(); // Update current line number and indentation from raw source code. - unsigned NewLineStart = 0; + bool SawNewLine = 0; for (unsigned I = LastOffset; I < Offset; ++I) { if (Code[I] == '\n') { - NewLineStart = I + 1; + LineStartOffset = I + 1; + SawNewLine = true; ++Line; } } - if (NewLineStart || !LastOffset) { + if (SawNewLine || !LastOffset) { Indent = 0; - for (char C : StringRef(Code).slice(NewLineStart, Offset)) { + for (char C : StringRef(Code).slice(LineStartOffset, Offset)) { if (C == ' ') ++Indent; else if (C == '\t') @@ -60,6 +62,7 @@ } Tok.Indent = Indent; Tok.Line = Line; + Tok.StartColumn = Offset - LineStartOffset; if (CT.isAtStartOfLine()) Tok.setFlag(LexFlags::StartsPPLine); Index: clang-tools-extra/pseudo/include/clang-pseudo/Token.h =================================================================== --- clang-tools-extra/pseudo/include/clang-pseudo/Token.h +++ clang-tools-extra/pseudo/include/clang-pseudo/Token.h @@ -63,6 +63,9 @@ /// Zero-based line number for the start of the token. /// This refers to the original source file as written. uint32_t Line = 0; + /// Zero-based column number for the start of the token. + /// This refers to the original source file as written. + uint8_t StartColumn = 0; /// Width of whitespace before the first token on this line. uint8_t Indent = 0; /// Flags have some meaning defined by the function that produced this stream. @@ -96,7 +99,7 @@ /// If this token is a paired bracket, the offset of the pair in the stream. int32_t Pair = 0; }; -static_assert(sizeof(Token) <= sizeof(char *) + 20, "Careful with layout!"); +static_assert(sizeof(Token) <= sizeof(char *) + 24, "Careful with layout!"); llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Token &); /// A half-open range of tokens within a stream. Index: clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp +++ clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp @@ -240,7 +240,7 @@ ]]} )cpp", R"cpp( - class Foo { + class Foo {[[ public: Foo() {[[ int X = 1; @@ -253,14 +253,15 @@ // Braces are located at the same line: no folding range here. void getFooBar() { } - }; + ]]}; )cpp", }; for (const char *Test : Tests) { auto T = Annotations(Test); auto AST = TestTU::withCode(T.code()).build(); - EXPECT_THAT(gatherFoldingRanges(llvm::cantFail(getFoldingRanges(AST))), - UnorderedElementsAreArray(T.ranges())) + EXPECT_THAT( + gatherFoldingRanges(llvm::cantFail(getFoldingRanges(T.code().str()))), + UnorderedElementsAreArray(T.ranges())) << Test; } } Index: clang-tools-extra/clangd/SemanticSelection.h =================================================================== --- clang-tools-extra/clangd/SemanticSelection.h +++ clang-tools-extra/clangd/SemanticSelection.h @@ -15,6 +15,7 @@ #include "ParsedAST.h" #include "Protocol.h" #include "llvm/Support/Error.h" +#include <string> #include <vector> namespace clang { namespace clangd { @@ -29,6 +30,10 @@ /// This should include large scopes, preprocessor blocks etc. llvm::Expected<std::vector<FoldingRange>> getFoldingRanges(ParsedAST &AST); +/// FILL ME. +llvm::Expected<std::vector<FoldingRange>> +getFoldingRanges(const std::string &Code); + } // namespace clangd } // namespace clang Index: clang-tools-extra/clangd/SemanticSelection.cpp =================================================================== --- clang-tools-extra/clangd/SemanticSelection.cpp +++ clang-tools-extra/clangd/SemanticSelection.cpp @@ -11,15 +11,20 @@ #include "Protocol.h" #include "Selection.h" #include "SourceCode.h" +#include "clang-pseudo/Bracket.h" +#include "clang-pseudo/DirectiveTree.h" +#include "clang-pseudo/Token.h" #include "clang/AST/DeclBase.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" +#include "clang/Basic/TokenKinds.h" #include "clang/Tooling/Syntax/BuildTree.h" #include "clang/Tooling/Syntax/Nodes.h" #include "clang/Tooling/Syntax/Tree.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Error.h" +#include "llvm/Support/raw_ostream.h" #include <queue> #include <vector> @@ -162,5 +167,38 @@ return collectFoldingRanges(SyntaxTree, AST.getSourceManager()); } +llvm::Expected<std::vector<FoldingRange>> +getFoldingRanges(const std::string &Code) { + auto Stream = clang::pseudo::lex(Code, clang::pseudo::genericLangOpts()); + + auto DirectiveStructure = clang::pseudo::DirectiveTree::parse(Stream); + clang::pseudo::chooseConditionalBranches(DirectiveStructure, Stream); + + llvm::Optional<pseudo::TokenStream> Preprocessed; + if (true) { + Preprocessed = DirectiveStructure.stripDirectives(Stream); + Stream = *Preprocessed; + } + + auto ParseableStream = clang::pseudo::stripComments( + cook(Stream, clang::pseudo::genericLangOpts())); + pseudo::pairBrackets(ParseableStream); + + std::vector<FoldingRange> Result; + for (const auto &Tok : ParseableStream.tokens()) { + if (auto *Paired = Tok.pair()) { + if (Tok.Line < Paired->Line) { + FoldingRange FR; + FR.startLine = Tok.Line; + FR.startCharacter = Tok.StartColumn + 1; + FR.endLine = Paired->Line; + FR.endCharacter = Paired->StartColumn; + Result.push_back(FR); + } + } + } + return Result; +} + } // namespace clangd } // namespace clang Index: clang-tools-extra/clangd/CMakeLists.txt =================================================================== --- clang-tools-extra/clangd/CMakeLists.txt +++ clang-tools-extra/clangd/CMakeLists.txt @@ -145,6 +145,10 @@ $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}> ) +target_include_directories(clangDaemon PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../pseudo/include +) + clang_target_link_libraries(clangDaemon PRIVATE clangAST @@ -170,6 +174,8 @@ clangTidy clangdSupport + + clangPseudo ) if(CLANGD_TIDY_CHECKS) target_link_libraries(clangDaemon PRIVATE ${ALL_CLANG_TIDY_CHECKS})
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits