forked from OSchip/llvm-project
[libTooling] Add `toString` method to the Stencil class
Summary: `toString` generates a string representation of the stencil. Patch by Harshal T. Lehri. Reviewers: gribozavr Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D68574 llvm-svn: 373916
This commit is contained in:
parent
9c2e123043
commit
d5b983555f
|
@ -50,6 +50,11 @@ public:
|
|||
|
||||
virtual bool isEqual(const StencilPartInterface &other) const = 0;
|
||||
|
||||
/// Constructs a string representation of the StencilPart. StencilParts
|
||||
/// generated by the `selection` and `run` functions do not have a unique
|
||||
/// string representation.
|
||||
virtual std::string toString() const = 0;
|
||||
|
||||
const void *typeId() const { return TypeId; }
|
||||
|
||||
protected:
|
||||
|
@ -86,6 +91,12 @@ public:
|
|||
return Impl->isEqual(*Other.Impl);
|
||||
}
|
||||
|
||||
std::string toString() const {
|
||||
if (Impl == nullptr)
|
||||
return "";
|
||||
return Impl->toString();
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<StencilPartInterface> Impl;
|
||||
};
|
||||
|
@ -120,6 +131,16 @@ public:
|
|||
return eval(Result);
|
||||
}
|
||||
|
||||
/// Constructs a string representation of the Stencil. The string is not
|
||||
/// guaranteed to be unique.
|
||||
std::string toString() const {
|
||||
std::vector<std::string> PartStrings;
|
||||
PartStrings.reserve(Parts.size());
|
||||
for (const auto &Part : Parts)
|
||||
PartStrings.push_back(Part.toString());
|
||||
return llvm::join(PartStrings, ", ");
|
||||
}
|
||||
|
||||
private:
|
||||
friend bool operator==(const Stencil &A, const Stencil &B);
|
||||
static StencilPart wrap(llvm::StringRef Text);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "clang/Lex/Lexer.h"
|
||||
#include "clang/Tooling/Refactoring/SourceCode.h"
|
||||
#include "clang/Tooling/Refactoring/SourceCodeBuilders.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/Support/Errc.h"
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
|
@ -128,6 +129,54 @@ bool isEqualData(const MatchConsumer<std::string> &A,
|
|||
return false;
|
||||
}
|
||||
|
||||
std::string toStringData(const RawTextData &Data) {
|
||||
std::string Result;
|
||||
llvm::raw_string_ostream OS(Result);
|
||||
OS << "\"";
|
||||
OS.write_escaped(Data.Text);
|
||||
OS << "\"";
|
||||
OS.flush();
|
||||
return Result;
|
||||
}
|
||||
|
||||
std::string toStringData(const DebugPrintNodeData &Data) {
|
||||
return (llvm::Twine("dPrint(\"") + Data.Id + "\")").str();
|
||||
}
|
||||
|
||||
std::string toStringData(const UnaryOperationData &Data) {
|
||||
StringRef OpName;
|
||||
switch (Data.Op) {
|
||||
case UnaryNodeOperator::Parens:
|
||||
OpName = "expression";
|
||||
break;
|
||||
case UnaryNodeOperator::Deref:
|
||||
OpName = "deref";
|
||||
break;
|
||||
case UnaryNodeOperator::Address:
|
||||
OpName = "addressOf";
|
||||
break;
|
||||
}
|
||||
return (OpName + "(\"" + Data.Id + "\")").str();
|
||||
}
|
||||
|
||||
std::string toStringData(const SelectorData &) { return "SelectorData()"; }
|
||||
|
||||
std::string toStringData(const AccessData &Data) {
|
||||
return (llvm::Twine("access(\"") + Data.BaseId + "\", " +
|
||||
Data.Member.toString() + ")")
|
||||
.str();
|
||||
}
|
||||
|
||||
std::string toStringData(const IfBoundData &Data) {
|
||||
return (llvm::Twine("ifBound(\"") + Data.Id + "\", " +
|
||||
Data.TruePart.toString() + ", " + Data.FalsePart.toString() + ")")
|
||||
.str();
|
||||
}
|
||||
|
||||
std::string toStringData(const MatchConsumer<std::string> &) {
|
||||
return "MatchConsumer<std::string>()";
|
||||
}
|
||||
|
||||
// The `evalData()` overloads evaluate the given stencil data to a string, given
|
||||
// the match result, and append it to `Result`. We define an overload for each
|
||||
// type of stencil data.
|
||||
|
@ -247,6 +296,8 @@ public:
|
|||
return isEqualData(Data, OtherPtr->Data);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string toString() const override { return toStringData(Data); }
|
||||
};
|
||||
} // namespace
|
||||
|
||||
|
|
|
@ -389,4 +389,59 @@ TEST(StencilEqualityTest, InEqualityRun) {
|
|||
auto S2 = cat(run(F));
|
||||
EXPECT_NE(S1, S2);
|
||||
}
|
||||
|
||||
TEST(StencilToStringTest, RawTextOp) {
|
||||
auto S = cat("foo bar baz");
|
||||
EXPECT_EQ(S.toString(), R"("foo bar baz")");
|
||||
}
|
||||
|
||||
TEST(StencilToStringTest, RawTextOpEscaping) {
|
||||
auto S = cat("foo \"bar\" baz\\n");
|
||||
EXPECT_EQ(S.toString(), R"("foo \"bar\" baz\\n")");
|
||||
}
|
||||
|
||||
TEST(StencilToStringTest, DebugPrintNodeOp) {
|
||||
auto S = cat(dPrint("Id"));
|
||||
EXPECT_EQ(S.toString(), R"repr(dPrint("Id"))repr");
|
||||
}
|
||||
|
||||
TEST(StencilToStringTest, ExpressionOp) {
|
||||
auto S = cat(expression("Id"));
|
||||
EXPECT_EQ(S.toString(), R"repr(expression("Id"))repr");
|
||||
}
|
||||
|
||||
TEST(StencilToStringTest, DerefOp) {
|
||||
auto S = cat(deref("Id"));
|
||||
EXPECT_EQ(S.toString(), R"repr(deref("Id"))repr");
|
||||
}
|
||||
|
||||
TEST(StencilToStringTest, AddressOfOp) {
|
||||
auto S = cat(addressOf("Id"));
|
||||
EXPECT_EQ(S.toString(), R"repr(addressOf("Id"))repr");
|
||||
}
|
||||
|
||||
TEST(StencilToStringTest, AccessOp) {
|
||||
auto S = cat(access("Id", text("memberData")));
|
||||
EXPECT_EQ(S.toString(), R"repr(access("Id", "memberData"))repr");
|
||||
}
|
||||
|
||||
TEST(StencilToStringTest, AccessOpStencilPart) {
|
||||
auto S = cat(access("Id", access("subId", "memberData")));
|
||||
EXPECT_EQ(S.toString(),
|
||||
R"repr(access("Id", access("subId", "memberData")))repr");
|
||||
}
|
||||
|
||||
TEST(StencilToStringTest, IfBoundOp) {
|
||||
auto S = cat(ifBound("Id", text("trueText"), access("exprId", "memberData")));
|
||||
EXPECT_EQ(
|
||||
S.toString(),
|
||||
R"repr(ifBound("Id", "trueText", access("exprId", "memberData")))repr");
|
||||
}
|
||||
|
||||
TEST(StencilToStringTest, MultipleOp) {
|
||||
auto S = cat("foo", access("x", "m()"), "bar",
|
||||
ifBound("x", text("t"), access("e", "f")));
|
||||
EXPECT_EQ(S.toString(), R"repr("foo", access("x", "m()"), "bar", )repr"
|
||||
R"repr(ifBound("x", "t", access("e", "f")))repr");
|
||||
}
|
||||
} // namespace
|
||||
|
|
Loading…
Reference in New Issue