| //===--- TestLexer.h - Format C++ code --------------------------*- 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 |
| // |
| //===----------------------------------------------------------------------===// |
| /// |
| /// \file |
| /// This file contains a TestLexer to create FormatTokens from strings. |
| /// |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef CLANG_UNITTESTS_FORMAT_TESTLEXER_H |
| #define CLANG_UNITTESTS_FORMAT_TESTLEXER_H |
| |
| #include "../../lib/Format/FormatTokenLexer.h" |
| #include "../../lib/Format/TokenAnalyzer.h" |
| #include "../../lib/Format/TokenAnnotator.h" |
| #include "../../lib/Format/UnwrappedLineParser.h" |
| |
| #include "clang/Basic/FileManager.h" |
| #include "clang/Basic/SourceManager.h" |
| |
| #include <numeric> |
| #include <ostream> |
| |
| namespace clang { |
| namespace format { |
| |
| typedef llvm::SmallVector<FormatToken *, 8> TokenList; |
| |
| inline std::ostream &operator<<(std::ostream &Stream, const FormatToken &Tok) { |
| Stream << "(" << Tok.Tok.getName() << ", \"" << Tok.TokenText.str() << "\" , " |
| << getTokenTypeName(Tok.getType()) << ")"; |
| return Stream; |
| } |
| inline std::ostream &operator<<(std::ostream &Stream, const TokenList &Tokens) { |
| Stream << "{"; |
| for (size_t I = 0, E = Tokens.size(); I != E; ++I) { |
| Stream << (I > 0 ? ", " : "") << *Tokens[I]; |
| } |
| Stream << "} (" << Tokens.size() << " tokens)"; |
| return Stream; |
| } |
| |
| inline TokenList uneof(const TokenList &Tokens) { |
| assert(!Tokens.empty() && Tokens.back()->is(tok::eof)); |
| return TokenList(Tokens.begin(), std::prev(Tokens.end())); |
| } |
| |
| inline std::string text(llvm::ArrayRef<FormatToken *> Tokens) { |
| return std::accumulate(Tokens.begin(), Tokens.end(), std::string(), |
| [](const std::string &R, FormatToken *Tok) { |
| return (R + Tok->TokenText).str(); |
| }); |
| } |
| |
| class TestLexer : public UnwrappedLineConsumer { |
| public: |
| TestLexer(llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator, |
| std::vector<std::unique_ptr<llvm::MemoryBuffer>> &Buffers, |
| FormatStyle Style = getLLVMStyle()) |
| : Allocator(Allocator), Buffers(Buffers), Style(Style), |
| SourceMgr("test.cpp", ""), IdentTable(getFormattingLangOpts(Style)) {} |
| |
| TokenList lex(llvm::StringRef Code) { |
| FormatTokenLexer Lex = getNewLexer(Code); |
| ArrayRef<FormatToken *> Result = Lex.lex(); |
| return TokenList(Result.begin(), Result.end()); |
| } |
| |
| TokenList annotate(llvm::StringRef Code) { |
| FormatTokenLexer Lex = getNewLexer(Code); |
| auto Tokens = Lex.lex(); |
| UnwrappedLineParser Parser(Style, Lex.getKeywords(), 0, Tokens, *this); |
| Parser.parse(); |
| TokenAnnotator Annotator(Style, Lex.getKeywords()); |
| for (auto &Line : UnwrappedLines) { |
| AnnotatedLine Annotated(Line); |
| Annotator.annotate(Annotated); |
| Annotator.calculateFormattingInformation(Annotated); |
| } |
| UnwrappedLines.clear(); |
| return TokenList(Tokens.begin(), Tokens.end()); |
| } |
| |
| FormatToken *id(llvm::StringRef Code) { |
| auto Result = uneof(lex(Code)); |
| assert(Result.size() == 1U && "Code must expand to 1 token."); |
| return Result[0]; |
| } |
| |
| protected: |
| void consumeUnwrappedLine(const UnwrappedLine &TheLine) override { |
| UnwrappedLines.push_back(TheLine); |
| } |
| void finishRun() override {} |
| |
| FormatTokenLexer getNewLexer(StringRef Code) { |
| Buffers.push_back( |
| llvm::MemoryBuffer::getMemBufferCopy(Code, "<scratch space>")); |
| clang::FileID FID = |
| SourceMgr.get().createFileID(Buffers.back()->getMemBufferRef()); |
| return FormatTokenLexer(SourceMgr.get(), FID, 0, Style, Encoding, Allocator, |
| IdentTable); |
| } |
| |
| public: |
| llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator; |
| std::vector<std::unique_ptr<llvm::MemoryBuffer>> &Buffers; |
| FormatStyle Style; |
| encoding::Encoding Encoding = encoding::Encoding_UTF8; |
| clang::SourceManagerForFile SourceMgr; |
| IdentifierTable IdentTable; |
| SmallVector<UnwrappedLine, 16> UnwrappedLines; |
| }; |
| |
| } // namespace format |
| } // namespace clang |
| |
| #endif // LLVM_CLANG_UNITTESTS_FORMAT_TEST_LEXER_H |