r373916 - [libTooling] Add `toString` method to the Stencil class
Yitzhak Mandelbaum via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 7 09:20:22 PDT 2019
Author: ymandel
Date: Mon Oct 7 09:20:22 2019
New Revision: 373916
URL: http://llvm.org/viewvc/llvm-project?rev=373916&view=rev
Log:
[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
Modified:
cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h
cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp
cfe/trunk/unittests/Tooling/StencilTest.cpp
Modified: cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h?rev=373916&r1=373915&r2=373916&view=diff
==============================================================================
--- cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h (original)
+++ cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h Mon Oct 7 09:20:22 2019
@@ -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);
Modified: cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp?rev=373916&r1=373915&r2=373916&view=diff
==============================================================================
--- cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp (original)
+++ cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp Mon Oct 7 09:20:22 2019
@@ -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
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
Modified: cfe/trunk/unittests/Tooling/StencilTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/StencilTest.cpp?rev=373916&r1=373915&r2=373916&view=diff
==============================================================================
--- cfe/trunk/unittests/Tooling/StencilTest.cpp (original)
+++ cfe/trunk/unittests/Tooling/StencilTest.cpp Mon Oct 7 09:20:22 2019
@@ -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
More information about the cfe-commits
mailing list