7
7
// ===----------------------------------------------------------------------===//
8
8
#include " llvm/Support/Mustache.h"
9
9
#include " llvm/ADT/SmallVector.h"
10
- #include " llvm/Support/Error.h"
11
10
#include " llvm/Support/raw_ostream.h"
12
11
#include < sstream>
13
12
@@ -23,6 +22,13 @@ static bool isFalsey(const json::Value &V) {
23
22
(V.getAsArray () && V.getAsArray ()->empty ());
24
23
}
25
24
25
+ static bool isContextFalsey (const json::Value *V) {
26
+ // A missing context (represented by a nullptr) is defined as falsey.
27
+ if (!V)
28
+ return true ;
29
+ return isFalsey (*V);
30
+ }
31
+
26
32
static Accessor splitMustacheString (StringRef Str) {
27
33
// We split the mustache string into an accessor.
28
34
// For example:
@@ -560,68 +566,71 @@ void toMustacheString(const json::Value &Data, raw_ostream &OS) {
560
566
}
561
567
}
562
568
563
- void ASTNode::render (const json::Value &Data, raw_ostream &OS) {
564
- ParentContext = &Data;
569
+ void ASTNode::render (const json::Value &CurrentCtx, raw_ostream &OS) {
570
+ // Set the parent context to the incoming context so that we
571
+ // can walk up the context tree correctly in findContext().
572
+ ParentContext = &CurrentCtx;
565
573
const json::Value *ContextPtr = Ty == Root ? ParentContext : findContext ();
566
- const json::Value &Context = ContextPtr ? *ContextPtr : nullptr ;
567
574
568
575
switch (Ty) {
569
576
case Root:
570
- renderChild (Data , OS);
577
+ renderChild (CurrentCtx , OS);
571
578
return ;
572
579
case Text:
573
580
OS << Body;
574
581
return ;
575
582
case Partial: {
576
583
auto Partial = Partials.find (AccessorValue[0 ]);
577
584
if (Partial != Partials.end ())
578
- renderPartial (Data , OS, Partial->getValue ().get ());
585
+ renderPartial (CurrentCtx , OS, Partial->getValue ().get ());
579
586
return ;
580
587
}
581
588
case Variable: {
582
589
auto Lambda = Lambdas.find (AccessorValue[0 ]);
583
- if (Lambda != Lambdas.end ())
584
- renderLambdas (Data , OS, Lambda->getValue ());
585
- else {
590
+ if (Lambda != Lambdas.end ()) {
591
+ renderLambdas (CurrentCtx , OS, Lambda->getValue ());
592
+ } else if (ContextPtr) {
586
593
EscapeStringStream ES (OS, Escapes);
587
- toMustacheString (Context , ES);
594
+ toMustacheString (*ContextPtr , ES);
588
595
}
589
596
return ;
590
597
}
591
598
case UnescapeVariable: {
592
599
auto Lambda = Lambdas.find (AccessorValue[0 ]);
593
- if (Lambda != Lambdas.end ())
594
- renderLambdas (Data, OS, Lambda->getValue ());
595
- else
596
- toMustacheString (Context, OS);
600
+ if (Lambda != Lambdas.end ()) {
601
+ renderLambdas (CurrentCtx, OS, Lambda->getValue ());
602
+ } else if (ContextPtr) {
603
+ toMustacheString (*ContextPtr, OS);
604
+ }
597
605
return ;
598
606
}
599
607
case Section: {
600
- // Sections are not rendered if the context is falsey.
601
608
auto SectionLambda = SectionLambdas.find (AccessorValue[0 ]);
602
609
bool IsLambda = SectionLambda != SectionLambdas.end ();
603
- if (isFalsey (Context) && !IsLambda)
604
- return ;
605
610
606
611
if (IsLambda) {
607
- renderSectionLambdas (Data , OS, SectionLambda->getValue ());
612
+ renderSectionLambdas (CurrentCtx , OS, SectionLambda->getValue ());
608
613
return ;
609
614
}
610
615
611
- if (Context.getAsArray ()) {
612
- const json::Array *Arr = Context.getAsArray ();
616
+ if (isContextFalsey (ContextPtr))
617
+ return ;
618
+
619
+ if (const json::Array *Arr = ContextPtr->getAsArray ()) {
613
620
for (const json::Value &V : *Arr)
614
621
renderChild (V, OS);
615
622
return ;
616
623
}
617
- renderChild (Context , OS);
624
+ renderChild (*ContextPtr , OS);
618
625
return ;
619
626
}
620
627
case InvertSection: {
621
628
bool IsLambda = SectionLambdas.contains (AccessorValue[0 ]);
622
- if (!isFalsey (Context) || IsLambda)
623
- return ;
624
- renderChild (Context, OS);
629
+ if (isContextFalsey (ContextPtr) && !IsLambda) {
630
+ // The context for the children remains unchanged from the parent's, so
631
+ // we pass this node's original incoming context.
632
+ renderChild (CurrentCtx, OS);
633
+ }
625
634
return ;
626
635
}
627
636
}
0 commit comments