[llvm-branch-commits] [llvm] [llvm][mustache] Add support for Triple Mustache (PR #159183)
Paul Kirth via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Sep 22 10:07:38 PDT 2025
https://github.com/ilovepi updated https://github.com/llvm/llvm-project/pull/159183
>From 30e848972cf380f7d726912419f2ba5c51341546 Mon Sep 17 00:00:00 2001
From: Paul Kirth <paulkirth at google.com>
Date: Fri, 29 Aug 2025 21:46:49 -0700
Subject: [PATCH] [llvm][mustache] Add support for Triple Mustache
We extend the logic in tokenize() to treat the `{{{}}}` delimiters
to treat it like other unescaped HTML. We do this by updating the
tokenizer to treat the new tokes the same way we do for the `{{&variable}}`
syntax, which avoid the need to change the parser.
We also update the llvm-test-mustache-spec tool to no longer mark Triple
Mustache as XFAIL.
---
llvm/lib/Support/Mustache.cpp | 39 +++++++++++++------
llvm/unittests/Support/MustacheTest.cpp | 20 +++++-----
.../llvm-test-mustache-spec.cpp | 14 -------
3 files changed, 38 insertions(+), 35 deletions(-)
diff --git a/llvm/lib/Support/Mustache.cpp b/llvm/lib/Support/Mustache.cpp
index 6c2ed6c84c6cf..be9cbfd46982f 100644
--- a/llvm/lib/Support/Mustache.cpp
+++ b/llvm/lib/Support/Mustache.cpp
@@ -305,6 +305,8 @@ SmallVector<Token> tokenize(StringRef Template) {
SmallVector<Token> Tokens;
StringLiteral Open("{{");
StringLiteral Close("}}");
+ StringLiteral TripleOpen("{{{");
+ StringLiteral TripleClose("}}}");
size_t Start = 0;
size_t DelimiterStart = Template.find(Open);
if (DelimiterStart == StringRef::npos) {
@@ -314,18 +316,33 @@ SmallVector<Token> tokenize(StringRef Template) {
while (DelimiterStart != StringRef::npos) {
if (DelimiterStart != Start)
Tokens.emplace_back(Template.substr(Start, DelimiterStart - Start).str());
- size_t DelimiterEnd = Template.find(Close, DelimiterStart);
- if (DelimiterEnd == StringRef::npos)
- break;
- // Extract the Interpolated variable without delimiters.
- size_t InterpolatedStart = DelimiterStart + Open.size();
- size_t InterpolatedEnd = DelimiterEnd - DelimiterStart - Close.size();
- std::string Interpolated =
- Template.substr(InterpolatedStart, InterpolatedEnd).str();
- std::string RawBody = Open.str() + Interpolated + Close.str();
- Tokens.emplace_back(RawBody, Interpolated, Interpolated[0]);
- Start = DelimiterEnd + Close.size();
+ if (Template.substr(DelimiterStart).starts_with(TripleOpen)) {
+ size_t DelimiterEnd = Template.find(TripleClose, DelimiterStart);
+ if (DelimiterEnd == StringRef::npos)
+ break;
+ size_t BodyStart = DelimiterStart + TripleOpen.size();
+ std::string Body =
+ Template.substr(BodyStart, DelimiterEnd - BodyStart).str();
+ std::string RawBody =
+ Template.substr(DelimiterStart, DelimiterEnd - DelimiterStart + 3)
+ .str();
+ Tokens.emplace_back(RawBody, "&" + Body, '&');
+ Start = DelimiterEnd + TripleClose.size();
+ } else {
+ size_t DelimiterEnd = Template.find(Close, DelimiterStart);
+ if (DelimiterEnd == StringRef::npos)
+ break;
+
+ // Extract the Interpolated variable without delimiters.
+ size_t InterpolatedStart = DelimiterStart + Open.size();
+ size_t InterpolatedEnd = DelimiterEnd - DelimiterStart - Close.size();
+ std::string Interpolated =
+ Template.substr(InterpolatedStart, InterpolatedEnd).str();
+ std::string RawBody = Open.str() + Interpolated + Close.str();
+ Tokens.emplace_back(RawBody, Interpolated, Interpolated[0]);
+ Start = DelimiterEnd + Close.size();
+ }
DelimiterStart = Template.find(Open, Start);
}
diff --git a/llvm/unittests/Support/MustacheTest.cpp b/llvm/unittests/Support/MustacheTest.cpp
index ddc9efc035e17..fb8478f368783 100644
--- a/llvm/unittests/Support/MustacheTest.cpp
+++ b/llvm/unittests/Support/MustacheTest.cpp
@@ -1235,7 +1235,7 @@ TEST(MustacheTripleMustache, Basic) {
std::string Out;
raw_string_ostream OS(Out);
T.render(D, OS);
- EXPECT_NE("Hello, <b>World</b>!", Out);
+ EXPECT_EQ("Hello, <b>World</b>!", Out);
}
TEST(MustacheTripleMustache, IntegerInterpolation) {
@@ -1244,7 +1244,7 @@ TEST(MustacheTripleMustache, IntegerInterpolation) {
std::string Out;
raw_string_ostream OS(Out);
T.render(D, OS);
- EXPECT_NE("85 miles an hour!", Out);
+ EXPECT_EQ("85 miles an hour!", Out);
}
TEST(MustacheTripleMustache, DecimalInterpolation) {
@@ -1253,7 +1253,7 @@ TEST(MustacheTripleMustache, DecimalInterpolation) {
std::string Out;
raw_string_ostream OS(Out);
T.render(D, OS);
- EXPECT_NE("1.21 jiggawatts!", Out);
+ EXPECT_EQ("1.21 jiggawatts!", Out);
}
TEST(MustacheTripleMustache, NullInterpolation) {
@@ -1262,7 +1262,7 @@ TEST(MustacheTripleMustache, NullInterpolation) {
std::string Out;
raw_string_ostream OS(Out);
T.render(D, OS);
- EXPECT_NE("I () be seen!", Out);
+ EXPECT_EQ("I () be seen!", Out);
}
TEST(MustacheTripleMustache, ContextMissInterpolation) {
@@ -1271,7 +1271,7 @@ TEST(MustacheTripleMustache, ContextMissInterpolation) {
std::string Out;
raw_string_ostream OS(Out);
T.render(D, OS);
- EXPECT_NE("I () be seen!", Out);
+ EXPECT_EQ("I () be seen!", Out);
}
TEST(MustacheTripleMustache, DottedNames) {
@@ -1280,7 +1280,7 @@ TEST(MustacheTripleMustache, DottedNames) {
std::string Out;
raw_string_ostream OS(Out);
T.render(D, OS);
- EXPECT_NE("<b>Joe</b>", Out);
+ EXPECT_EQ("<b>Joe</b>", Out);
}
TEST(MustacheTripleMustache, ImplicitIterator) {
@@ -1289,7 +1289,7 @@ TEST(MustacheTripleMustache, ImplicitIterator) {
std::string Out;
raw_string_ostream OS(Out);
T.render(D, OS);
- EXPECT_NE("(<a>)(<b>)", Out);
+ EXPECT_EQ("(<a>)(<b>)", Out);
}
TEST(MustacheTripleMustache, SurroundingWhitespace) {
@@ -1298,7 +1298,7 @@ TEST(MustacheTripleMustache, SurroundingWhitespace) {
std::string Out;
raw_string_ostream OS(Out);
T.render(D, OS);
- EXPECT_NE("| --- |", Out);
+ EXPECT_EQ("| --- |", Out);
}
TEST(MustacheTripleMustache, Standalone) {
@@ -1307,7 +1307,7 @@ TEST(MustacheTripleMustache, Standalone) {
std::string Out;
raw_string_ostream OS(Out);
T.render(D, OS);
- EXPECT_NE(" ---\n", Out);
+ EXPECT_EQ(" ---\n", Out);
}
TEST(MustacheTripleMustache, WithPadding) {
@@ -1316,5 +1316,5 @@ TEST(MustacheTripleMustache, WithPadding) {
std::string Out;
raw_string_ostream OS(Out);
T.render(D, OS);
- EXPECT_NE("|---|", Out);
+ EXPECT_EQ("|---|", Out);
}
diff --git a/llvm/utils/llvm-test-mustache-spec/llvm-test-mustache-spec.cpp b/llvm/utils/llvm-test-mustache-spec/llvm-test-mustache-spec.cpp
index 1f566e13f070a..ea1395b2646f6 100644
--- a/llvm/utils/llvm-test-mustache-spec/llvm-test-mustache-spec.cpp
+++ b/llvm/utils/llvm-test-mustache-spec/llvm-test-mustache-spec.cpp
@@ -128,21 +128,7 @@ static const StringMap<StringSet<>> XFailTestNames = {{
"Section - Multiple Calls",
}},
- {"interpolation.json",
- {
- "Triple Mustache",
- "Triple Mustache Integer Interpolation",
- "Triple Mustache Decimal Interpolation",
- "Triple Mustache Null Interpolation",
- "Triple Mustache Context Miss Interpolation",
- "Dotted Names - Triple Mustache Interpolation",
- "Implicit Iterators - Triple Mustache",
- "Triple Mustache - Surrounding Whitespace",
- "Triple Mustache - Standalone",
- "Triple Mustache With Padding",
- }},
{"partials.json", {"Standalone Indentation"}},
- {"sections.json", {"Implicit Iterator - Triple mustache"}},
}};
struct TestData {
More information about the llvm-branch-commits
mailing list