1 //===--- TestLexer.h - Format C++ code --------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 /// This file contains a TestLexer to create FormatTokens from strings.
12 //===----------------------------------------------------------------------===//
14 #ifndef CLANG_UNITTESTS_FORMAT_TESTLEXER_H
15 #define CLANG_UNITTESTS_FORMAT_TESTLEXER_H
17 #include "../../lib/Format/FormatTokenLexer.h"
18 #include "../../lib/Format/TokenAnalyzer.h"
19 #include "../../lib/Format/TokenAnnotator.h"
20 #include "../../lib/Format/UnwrappedLineParser.h"
22 #include "clang/Basic/FileManager.h"
23 #include "clang/Basic/SourceManager.h"
31 typedef SmallVector
<FormatToken
*, 8> TokenList
;
33 inline std::ostream
&operator<<(std::ostream
&Stream
, const FormatToken
&Tok
) {
34 Stream
<< "(" << Tok
.Tok
.getName() << ", \"" << Tok
.TokenText
.str() << "\" , "
35 << getTokenTypeName(Tok
.getType()) << ")";
38 inline std::ostream
&operator<<(std::ostream
&Stream
, const TokenList
&Tokens
) {
40 for (size_t I
= 0, E
= Tokens
.size(); I
!= E
; ++I
)
41 Stream
<< (I
> 0 ? ", " : "") << *Tokens
[I
];
42 Stream
<< "} (" << Tokens
.size() << " tokens)";
46 inline TokenList
uneof(const TokenList
&Tokens
) {
47 assert(!Tokens
.empty() && Tokens
.back()->is(tok::eof
));
48 return TokenList(Tokens
.begin(), std::prev(Tokens
.end()));
51 inline std::string
text(ArrayRef
<FormatToken
*> Tokens
) {
52 return std::accumulate(Tokens
.begin(), Tokens
.end(), std::string(),
53 [](const std::string
&R
, FormatToken
*Tok
) {
54 return (R
+ Tok
->TokenText
).str();
58 class TestLexer
: public UnwrappedLineConsumer
{
60 TestLexer(llvm::SpecificBumpPtrAllocator
<FormatToken
> &Allocator
,
61 std::vector
<std::unique_ptr
<llvm::MemoryBuffer
>> &Buffers
,
62 FormatStyle Style
= getLLVMStyle())
63 : Allocator(Allocator
), Buffers(Buffers
), Style(Style
),
64 SourceMgr("test.cpp", ""), IdentTable(getFormattingLangOpts(Style
)) {}
66 TokenList
lex(StringRef Code
) {
67 FormatTokenLexer Lex
= getNewLexer(Code
);
68 ArrayRef
<FormatToken
*> Result
= Lex
.lex();
69 return TokenList(Result
.begin(), Result
.end());
72 TokenList
annotate(StringRef Code
) {
73 FormatTokenLexer Lex
= getNewLexer(Code
);
74 auto Tokens
= Lex
.lex();
75 UnwrappedLineParser
Parser(SourceMgr
.get(), Style
, Lex
.getKeywords(), 0,
76 Tokens
, *this, Allocator
, IdentTable
);
78 TokenAnnotator
Annotator(Style
, Lex
.getKeywords());
79 for (auto &Line
: UnwrappedLines
) {
80 AnnotatedLine
Annotated(Line
);
81 Annotator
.annotate(Annotated
);
82 Annotator
.calculateFormattingInformation(Annotated
);
84 UnwrappedLines
.clear();
85 return TokenList(Tokens
.begin(), Tokens
.end());
88 FormatToken
*id(StringRef Code
) {
89 auto Result
= uneof(lex(Code
));
90 assert(Result
.size() == 1U && "Code must expand to 1 token.");
95 void consumeUnwrappedLine(const UnwrappedLine
&TheLine
) override
{
96 UnwrappedLines
.push_back(TheLine
);
98 void finishRun() override
{}
100 FormatTokenLexer
getNewLexer(StringRef Code
) {
102 llvm::MemoryBuffer::getMemBufferCopy(Code
, "<scratch space>"));
104 SourceMgr
.get().createFileID(Buffers
.back()->getMemBufferRef());
105 return FormatTokenLexer(SourceMgr
.get(), FID
, 0, Style
, Encoding
, Allocator
,
110 llvm::SpecificBumpPtrAllocator
<FormatToken
> &Allocator
;
111 std::vector
<std::unique_ptr
<llvm::MemoryBuffer
>> &Buffers
;
113 encoding::Encoding Encoding
= encoding::Encoding_UTF8
;
114 SourceManagerForFile SourceMgr
;
115 IdentifierTable IdentTable
;
116 SmallVector
<UnwrappedLine
, 16> UnwrappedLines
;
119 } // namespace format
122 #endif // LLVM_CLANG_UNITTESTS_FORMAT_TEST_LEXER_H