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 <paulki...@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 {

_______________________________________________
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to