Skip to content

Commit 1c6e896

Browse files
authored
[llvm][mustache] Add support for Triple Mustache (#159183)
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.
1 parent 18cffb8 commit 1c6e896

File tree

3 files changed

+38
-35
lines changed

3 files changed

+38
-35
lines changed

llvm/lib/Support/Mustache.cpp

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,8 @@ SmallVector<Token> tokenize(StringRef Template) {
305305
SmallVector<Token> Tokens;
306306
StringLiteral Open("{{");
307307
StringLiteral Close("}}");
308+
StringLiteral TripleOpen("{{{");
309+
StringLiteral TripleClose("}}}");
308310
size_t Start = 0;
309311
size_t DelimiterStart = Template.find(Open);
310312
if (DelimiterStart == StringRef::npos) {
@@ -314,18 +316,33 @@ SmallVector<Token> tokenize(StringRef Template) {
314316
while (DelimiterStart != StringRef::npos) {
315317
if (DelimiterStart != Start)
316318
Tokens.emplace_back(Template.substr(Start, DelimiterStart - Start).str());
317-
size_t DelimiterEnd = Template.find(Close, DelimiterStart);
318-
if (DelimiterEnd == StringRef::npos)
319-
break;
320319

321-
// Extract the Interpolated variable without delimiters.
322-
size_t InterpolatedStart = DelimiterStart + Open.size();
323-
size_t InterpolatedEnd = DelimiterEnd - DelimiterStart - Close.size();
324-
std::string Interpolated =
325-
Template.substr(InterpolatedStart, InterpolatedEnd).str();
326-
std::string RawBody = Open.str() + Interpolated + Close.str();
327-
Tokens.emplace_back(RawBody, Interpolated, Interpolated[0]);
328-
Start = DelimiterEnd + Close.size();
320+
if (Template.substr(DelimiterStart).starts_with(TripleOpen)) {
321+
size_t DelimiterEnd = Template.find(TripleClose, DelimiterStart);
322+
if (DelimiterEnd == StringRef::npos)
323+
break;
324+
size_t BodyStart = DelimiterStart + TripleOpen.size();
325+
std::string Body =
326+
Template.substr(BodyStart, DelimiterEnd - BodyStart).str();
327+
std::string RawBody =
328+
Template.substr(DelimiterStart, DelimiterEnd - DelimiterStart + 3)
329+
.str();
330+
Tokens.emplace_back(RawBody, "&" + Body, '&');
331+
Start = DelimiterEnd + TripleClose.size();
332+
} else {
333+
size_t DelimiterEnd = Template.find(Close, DelimiterStart);
334+
if (DelimiterEnd == StringRef::npos)
335+
break;
336+
337+
// Extract the Interpolated variable without delimiters.
338+
size_t InterpolatedStart = DelimiterStart + Open.size();
339+
size_t InterpolatedEnd = DelimiterEnd - DelimiterStart - Close.size();
340+
std::string Interpolated =
341+
Template.substr(InterpolatedStart, InterpolatedEnd).str();
342+
std::string RawBody = Open.str() + Interpolated + Close.str();
343+
Tokens.emplace_back(RawBody, Interpolated, Interpolated[0]);
344+
Start = DelimiterEnd + Close.size();
345+
}
329346
DelimiterStart = Template.find(Open, Start);
330347
}
331348

llvm/unittests/Support/MustacheTest.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,7 +1235,7 @@ TEST(MustacheTripleMustache, Basic) {
12351235
std::string Out;
12361236
raw_string_ostream OS(Out);
12371237
T.render(D, OS);
1238-
EXPECT_NE("Hello, <b>World</b>!", Out);
1238+
EXPECT_EQ("Hello, <b>World</b>!", Out);
12391239
}
12401240

12411241
TEST(MustacheTripleMustache, IntegerInterpolation) {
@@ -1244,7 +1244,7 @@ TEST(MustacheTripleMustache, IntegerInterpolation) {
12441244
std::string Out;
12451245
raw_string_ostream OS(Out);
12461246
T.render(D, OS);
1247-
EXPECT_NE("85 miles an hour!", Out);
1247+
EXPECT_EQ("85 miles an hour!", Out);
12481248
}
12491249

12501250
TEST(MustacheTripleMustache, DecimalInterpolation) {
@@ -1253,7 +1253,7 @@ TEST(MustacheTripleMustache, DecimalInterpolation) {
12531253
std::string Out;
12541254
raw_string_ostream OS(Out);
12551255
T.render(D, OS);
1256-
EXPECT_NE("1.21 jiggawatts!", Out);
1256+
EXPECT_EQ("1.21 jiggawatts!", Out);
12571257
}
12581258

12591259
TEST(MustacheTripleMustache, NullInterpolation) {
@@ -1262,7 +1262,7 @@ TEST(MustacheTripleMustache, NullInterpolation) {
12621262
std::string Out;
12631263
raw_string_ostream OS(Out);
12641264
T.render(D, OS);
1265-
EXPECT_NE("I () be seen!", Out);
1265+
EXPECT_EQ("I () be seen!", Out);
12661266
}
12671267

12681268
TEST(MustacheTripleMustache, ContextMissInterpolation) {
@@ -1271,7 +1271,7 @@ TEST(MustacheTripleMustache, ContextMissInterpolation) {
12711271
std::string Out;
12721272
raw_string_ostream OS(Out);
12731273
T.render(D, OS);
1274-
EXPECT_NE("I () be seen!", Out);
1274+
EXPECT_EQ("I () be seen!", Out);
12751275
}
12761276

12771277
TEST(MustacheTripleMustache, DottedNames) {
@@ -1280,7 +1280,7 @@ TEST(MustacheTripleMustache, DottedNames) {
12801280
std::string Out;
12811281
raw_string_ostream OS(Out);
12821282
T.render(D, OS);
1283-
EXPECT_NE("<b>Joe</b>", Out);
1283+
EXPECT_EQ("<b>Joe</b>", Out);
12841284
}
12851285

12861286
TEST(MustacheTripleMustache, ImplicitIterator) {
@@ -1289,7 +1289,7 @@ TEST(MustacheTripleMustache, ImplicitIterator) {
12891289
std::string Out;
12901290
raw_string_ostream OS(Out);
12911291
T.render(D, OS);
1292-
EXPECT_NE("(<a>)(<b>)", Out);
1292+
EXPECT_EQ("(<a>)(<b>)", Out);
12931293
}
12941294

12951295
TEST(MustacheTripleMustache, SurroundingWhitespace) {
@@ -1298,7 +1298,7 @@ TEST(MustacheTripleMustache, SurroundingWhitespace) {
12981298
std::string Out;
12991299
raw_string_ostream OS(Out);
13001300
T.render(D, OS);
1301-
EXPECT_NE("| --- |", Out);
1301+
EXPECT_EQ("| --- |", Out);
13021302
}
13031303

13041304
TEST(MustacheTripleMustache, Standalone) {
@@ -1307,7 +1307,7 @@ TEST(MustacheTripleMustache, Standalone) {
13071307
std::string Out;
13081308
raw_string_ostream OS(Out);
13091309
T.render(D, OS);
1310-
EXPECT_NE(" ---\n", Out);
1310+
EXPECT_EQ(" ---\n", Out);
13111311
}
13121312

13131313
TEST(MustacheTripleMustache, WithPadding) {
@@ -1316,5 +1316,5 @@ TEST(MustacheTripleMustache, WithPadding) {
13161316
std::string Out;
13171317
raw_string_ostream OS(Out);
13181318
T.render(D, OS);
1319-
EXPECT_NE("|---|", Out);
1319+
EXPECT_EQ("|---|", Out);
13201320
}

llvm/utils/llvm-test-mustache-spec/llvm-test-mustache-spec.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -128,21 +128,7 @@ static const StringMap<StringSet<>> XFailTestNames = {{
128128
"Section - Multiple Calls",
129129

130130
}},
131-
{"interpolation.json",
132-
{
133-
"Triple Mustache",
134-
"Triple Mustache Integer Interpolation",
135-
"Triple Mustache Decimal Interpolation",
136-
"Triple Mustache Null Interpolation",
137-
"Triple Mustache Context Miss Interpolation",
138-
"Dotted Names - Triple Mustache Interpolation",
139-
"Implicit Iterators - Triple Mustache",
140-
"Triple Mustache - Surrounding Whitespace",
141-
"Triple Mustache - Standalone",
142-
"Triple Mustache With Padding",
143-
}},
144131
{"partials.json", {"Standalone Indentation"}},
145-
{"sections.json", {"Implicit Iterator - Triple mustache"}},
146132
}};
147133

148134
struct TestData {

0 commit comments

Comments
 (0)