ymandel created this revision.
ymandel added a reviewer: gribozavr.
Herald added a project: clang.
This revision adds `run`, a StencilPart that runs a user-defined function that
computes a result over `MatchFinder::MatchResult`.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D67969
Files:
clang/include/clang/Tooling/Refactoring/Stencil.h
clang/lib/Tooling/Refactoring/Stencil.cpp
clang/unittests/Tooling/StencilTest.cpp
Index: clang/unittests/Tooling/StencilTest.cpp
===================================================================
--- clang/unittests/Tooling/StencilTest.cpp
+++ clang/unittests/Tooling/StencilTest.cpp
@@ -29,6 +29,7 @@
using stencil::cat;
using stencil::dPrint;
using stencil::ifBound;
+using stencil::run;
using stencil::text;
// In tests, we can't directly match on llvm::Expected since its accessors
@@ -300,6 +301,15 @@
EXPECT_THAT_EXPECTED(Stencil.eval(StmtMatch->Result), HasValue("field"));
}
+TEST_F(StencilTest, RunOp) {
+ StringRef Id = "id";
+ auto SimpleFn = [Id](const MatchResult &R) {
+ return std::string(R.Nodes.getNodeAs<Stmt>(Id) != nullptr ? "Bound"
+ : "Unbound");
+ };
+ testExpr(Id, "3;", cat(run(SimpleFn)), "Bound");
+}
+
TEST(StencilEqualityTest, Equality) {
auto Lhs = cat("foo", dPrint("dprint_id"));
auto Rhs = cat("foo", dPrint("dprint_id"));
@@ -324,4 +334,12 @@
auto S2 = cat(node("node"));
EXPECT_NE(S1, S2);
}
+
+// `run` is opaque.
+TEST(StencilEqualityTest, InEqualityRun) {
+ auto F = [](const MatchResult &R) { return "foo"; };
+ auto S1 = cat(run(F));
+ auto S2 = cat(run(F));
+ EXPECT_NE(S1, S2);
+}
} // namespace
Index: clang/lib/Tooling/Refactoring/Stencil.cpp
===================================================================
--- clang/lib/Tooling/Refactoring/Stencil.cpp
+++ clang/lib/Tooling/Refactoring/Stencil.cpp
@@ -26,6 +26,7 @@
using ast_matchers::MatchFinder;
using llvm::errc;
using llvm::Error;
+using llvm::Expected;
using llvm::StringError;
// A down_cast function to safely down cast a StencilPartInterface to a subclass
@@ -102,6 +103,9 @@
return A.Id == B.Id && A.TruePart == B.TruePart && A.FalsePart == B.FalsePart;
}
+// Equality is not defined over MatchConsumer<std::string>s. They are, by definition, opaque.
+bool isEqualData(const MatchConsumer<std::string> &A, const MatchConsumer<std::string> &B) { return false; }
+
// 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.
@@ -159,6 +163,15 @@
.eval(Match, Result);
}
+Error evalData(const MatchConsumer<std::string> &Fn, const MatchFinder::MatchResult &Match,
+ std::string *Result) {
+ Expected<std::string> Value = Fn(Match);
+ if (!Value)
+ return Value.takeError();
+ *Result += *Value;
+ return Error::success();
+}
+
template <typename T>
class StencilPartImpl : public StencilPartInterface {
T Data;
@@ -233,3 +246,9 @@
return StencilPart(std::make_shared<StencilPartImpl<IfBoundData>>(
Id, std::move(TruePart), std::move(FalsePart)));
}
+
+StencilPart stencil::run(MatchConsumer<std::string> Fn) {
+ return StencilPart(
+ std::make_shared<StencilPartImpl<MatchConsumer<std::string>>>(
+ std::move(Fn)));
+}
Index: clang/include/clang/Tooling/Refactoring/Stencil.h
===================================================================
--- clang/include/clang/Tooling/Refactoring/Stencil.h
+++ clang/include/clang/Tooling/Refactoring/Stencil.h
@@ -23,6 +23,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTTypeTraits.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/Refactoring/MatchConsumer.h"
#include "clang/Tooling/Refactoring/RangeSelector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
@@ -175,6 +176,10 @@
return ifBound(Id, text(TrueText), text(FalseText));
}
+/// Wraps a MatchConsumer in a StencilPart, so that it can be used in a Stencil.
+/// This supports user-defined extensions to the Stencil language.
+StencilPart run(MatchConsumer<std::string> C);
+
/// For debug use only; semantics are not guaranteed.
///
/// \returns the string resulting from calling the node's print() method.
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits