2020-07-07 18:17:14 +08:00
|
|
|
//===--- TestLexer.h - Format C++ code --------------------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
///
|
|
|
|
/// \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"
|
2020-10-27 18:05:55 +08:00
|
|
|
#include "../../lib/Format/TokenAnalyzer.h"
|
|
|
|
#include "../../lib/Format/TokenAnnotator.h"
|
|
|
|
#include "../../lib/Format/UnwrappedLineParser.h"
|
2020-07-07 18:17:14 +08:00
|
|
|
|
|
|
|
#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) {
|
2020-10-27 18:05:55 +08:00
|
|
|
Stream << "(" << Tok.Tok.getName() << ", \"" << Tok.TokenText.str() << "\" , "
|
|
|
|
<< getTokenTypeName(Tok.getType()) << ")";
|
2020-07-07 18:17:14 +08:00
|
|
|
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];
|
|
|
|
}
|
2020-10-27 18:05:55 +08:00
|
|
|
Stream << "} (" << Tokens.size() << " tokens)";
|
2020-07-07 18:17:14 +08:00
|
|
|
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();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-10-27 18:05:55 +08:00
|
|
|
class TestLexer : public UnwrappedLineConsumer {
|
2020-07-07 18:17:14 +08:00
|
|
|
public:
|
2020-10-27 22:26:23 +08:00
|
|
|
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)) {}
|
2020-07-07 18:17:14 +08:00
|
|
|
|
|
|
|
TokenList lex(llvm::StringRef Code) {
|
2020-10-27 22:26:23 +08:00
|
|
|
FormatTokenLexer Lex = getNewLexer(Code);
|
|
|
|
ArrayRef<FormatToken *> Result = Lex.lex();
|
2020-07-07 18:17:14 +08:00
|
|
|
return TokenList(Result.begin(), Result.end());
|
|
|
|
}
|
|
|
|
|
2020-10-27 18:05:55 +08:00
|
|
|
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);
|
2020-10-27 22:26:23 +08:00
|
|
|
Annotator.calculateFormattingInformation(Annotated);
|
2020-10-27 18:05:55 +08:00
|
|
|
}
|
|
|
|
UnwrappedLines.clear();
|
|
|
|
return TokenList(Tokens.begin(), Tokens.end());
|
|
|
|
}
|
|
|
|
|
2020-07-07 18:17:14 +08:00
|
|
|
FormatToken *id(llvm::StringRef Code) {
|
|
|
|
auto Result = uneof(lex(Code));
|
|
|
|
assert(Result.size() == 1U && "Code must expand to 1 token.");
|
|
|
|
return Result[0];
|
|
|
|
}
|
|
|
|
|
2020-10-27 18:05:55 +08:00
|
|
|
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:
|
2020-10-27 22:26:23 +08:00
|
|
|
llvm::SpecificBumpPtrAllocator<FormatToken>& Allocator;
|
|
|
|
std::vector<std::unique_ptr<llvm::MemoryBuffer>>& Buffers;
|
2020-10-07 23:29:22 +08:00
|
|
|
FormatStyle Style;
|
2020-07-07 18:17:14 +08:00
|
|
|
encoding::Encoding Encoding = encoding::Encoding_UTF8;
|
|
|
|
clang::SourceManagerForFile SourceMgr;
|
|
|
|
IdentifierTable IdentTable;
|
2020-10-27 18:05:55 +08:00
|
|
|
SmallVector<UnwrappedLine, 16> UnwrappedLines;
|
2020-07-07 18:17:14 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace format
|
|
|
|
} // namespace clang
|
|
|
|
|
|
|
|
#endif // LLVM_CLANG_UNITTESTS_FORMAT_TEST_LEXER_H
|