Skip to content

Commit 8175095

Browse files
committed
[llvm][mustache] Refactor template rendering
Move the rendering logic into the ASTNode, and break the logic down into individual methods.
1 parent c8b70b1 commit 8175095

File tree

1 file changed

+92
-64
lines changed

1 file changed

+92
-64
lines changed

llvm/lib/Support/Mustache.cpp

Lines changed: 92 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,14 @@ class ASTNode {
181181

182182
const llvm::json::Value *findContext();
183183

184+
void renderRoot(const json::Value &CurrentCtx, raw_ostream &OS);
185+
void renderText(raw_ostream &OS);
186+
void renderPartial(const json::Value &CurrentCtx, raw_ostream &OS);
187+
void renderVariable(const json::Value &CurrentCtx, raw_ostream &OS);
188+
void renderUnescapeVariable(const json::Value &CurrentCtx, raw_ostream &OS);
189+
void renderSection(const json::Value &CurrentCtx, raw_ostream &OS);
190+
void renderInvertSection(const json::Value &CurrentCtx, raw_ostream &OS);
191+
184192
StringMap<AstPtr> &Partials;
185193
StringMap<Lambda> &Lambdas;
186194
StringMap<SectionLambda> &SectionLambdas;
@@ -198,26 +206,26 @@ class ASTNode {
198206

199207
// A wrapper for arena allocator for ASTNodes
200208
static AstPtr createRootNode(llvm::StringMap<AstPtr> &Partials,
201-
llvm::StringMap<Lambda> &Lambdas,
202-
llvm::StringMap<SectionLambda> &SectionLambdas,
203-
EscapeMap &Escapes) {
209+
llvm::StringMap<Lambda> &Lambdas,
210+
llvm::StringMap<SectionLambda> &SectionLambdas,
211+
EscapeMap &Escapes) {
204212
return std::make_unique<ASTNode>(Partials, Lambdas, SectionLambdas, Escapes);
205213
}
206214

207215
static AstPtr createNode(ASTNode::Type T, Accessor A, ASTNode *Parent,
208-
llvm::StringMap<AstPtr> &Partials,
209-
llvm::StringMap<Lambda> &Lambdas,
210-
llvm::StringMap<SectionLambda> &SectionLambdas,
211-
EscapeMap &Escapes) {
216+
llvm::StringMap<AstPtr> &Partials,
217+
llvm::StringMap<Lambda> &Lambdas,
218+
llvm::StringMap<SectionLambda> &SectionLambdas,
219+
EscapeMap &Escapes) {
212220
return std::make_unique<ASTNode>(T, std::move(A), Parent, Partials, Lambdas,
213221
SectionLambdas, Escapes);
214222
}
215223

216224
static AstPtr createTextNode(std::string Body, ASTNode *Parent,
217-
llvm::StringMap<AstPtr> &Partials,
218-
llvm::StringMap<Lambda> &Lambdas,
219-
llvm::StringMap<SectionLambda> &SectionLambdas,
220-
EscapeMap &Escapes) {
225+
llvm::StringMap<AstPtr> &Partials,
226+
llvm::StringMap<Lambda> &Lambdas,
227+
llvm::StringMap<SectionLambda> &SectionLambdas,
228+
EscapeMap &Escapes) {
221229
return std::make_unique<ASTNode>(std::move(Body), Parent, Partials, Lambdas,
222230
SectionLambdas, Escapes);
223231
}
@@ -295,7 +303,7 @@ static void stripTokenAhead(SmallVectorImpl<Token> &Tokens, size_t Idx) {
295303
// The exception for this is partial tag which requires us to
296304
// keep track of the indentation once it's rendered.
297305
static void stripTokenBefore(SmallVectorImpl<Token> &Tokens, size_t Idx,
298-
Token &CurrentToken, Token::Type CurrentType) {
306+
Token &CurrentToken, Token::Type CurrentType) {
299307
Token &PrevToken = Tokens[Idx - 1];
300308
StringRef PrevTokenBody = PrevToken.TokenBody;
301309
StringRef Unindented = PrevTokenBody.rtrim(" \r\t\v");
@@ -676,76 +684,96 @@ static void toMustacheString(const json::Value &Data, raw_ostream &OS) {
676684
}
677685
}
678686

687+
void ASTNode::renderRoot(const json::Value &CurrentCtx, raw_ostream &OS) {
688+
renderChild(CurrentCtx, OS);
689+
}
690+
691+
void ASTNode::renderText(raw_ostream &OS) { OS << Body; }
692+
693+
void ASTNode::renderPartial(const json::Value &CurrentCtx, raw_ostream &OS) {
694+
auto Partial = Partials.find(AccessorValue[0]);
695+
if (Partial != Partials.end())
696+
renderPartial(CurrentCtx, OS, Partial->getValue().get());
697+
}
698+
699+
void ASTNode::renderVariable(const json::Value &CurrentCtx, raw_ostream &OS) {
700+
auto Lambda = Lambdas.find(AccessorValue[0]);
701+
if (Lambda != Lambdas.end()) {
702+
renderLambdas(CurrentCtx, OS, Lambda->getValue());
703+
} else if (const json::Value *ContextPtr = findContext()) {
704+
EscapeStringStream ES(OS, Escapes);
705+
toMustacheString(*ContextPtr, ES);
706+
}
707+
}
708+
709+
void ASTNode::renderUnescapeVariable(const json::Value &CurrentCtx,
710+
raw_ostream &OS) {
711+
auto Lambda = Lambdas.find(AccessorValue[0]);
712+
if (Lambda != Lambdas.end()) {
713+
renderLambdas(CurrentCtx, OS, Lambda->getValue());
714+
} else if (const json::Value *ContextPtr = findContext()) {
715+
toMustacheString(*ContextPtr, OS);
716+
}
717+
}
718+
719+
void ASTNode::renderSection(const json::Value &CurrentCtx, raw_ostream &OS) {
720+
auto SectionLambda = SectionLambdas.find(AccessorValue[0]);
721+
if (SectionLambda != SectionLambdas.end()) {
722+
renderSectionLambdas(CurrentCtx, OS, SectionLambda->getValue());
723+
return;
724+
}
725+
726+
const json::Value *ContextPtr = findContext();
727+
if (isContextFalsey(ContextPtr))
728+
return;
729+
730+
if (const json::Array *Arr = ContextPtr->getAsArray()) {
731+
for (const json::Value &V : *Arr)
732+
renderChild(V, OS);
733+
return;
734+
}
735+
renderChild(*ContextPtr, OS);
736+
}
737+
738+
void ASTNode::renderInvertSection(const json::Value &CurrentCtx,
739+
raw_ostream &OS) {
740+
bool IsLambda = SectionLambdas.contains(AccessorValue[0]);
741+
const json::Value *ContextPtr = findContext();
742+
if (isContextFalsey(ContextPtr) && !IsLambda) {
743+
renderChild(CurrentCtx, OS);
744+
}
745+
}
746+
679747
void ASTNode::render(const json::Value &CurrentCtx, raw_ostream &OS) {
680748
if (Ty != Root && Ty != Text && AccessorValue.empty())
681749
return;
682750
// Set the parent context to the incoming context so that we
683751
// can walk up the context tree correctly in findContext().
684752
ParentContext = &CurrentCtx;
685-
const json::Value *ContextPtr = Ty == Root ? ParentContext : findContext();
686753

687754
switch (Ty) {
688755
case Root:
689-
renderChild(CurrentCtx, OS);
756+
renderRoot(CurrentCtx, OS);
690757
return;
691758
case Text:
692-
OS << Body;
759+
renderText(OS);
693760
return;
694-
case Partial: {
695-
auto Partial = Partials.find(AccessorValue[0]);
696-
if (Partial != Partials.end())
697-
renderPartial(CurrentCtx, OS, Partial->getValue().get());
761+
case Partial:
762+
renderPartial(CurrentCtx, OS);
698763
return;
699-
}
700-
case Variable: {
701-
auto Lambda = Lambdas.find(AccessorValue[0]);
702-
if (Lambda != Lambdas.end()) {
703-
renderLambdas(CurrentCtx, OS, Lambda->getValue());
704-
} else if (ContextPtr) {
705-
EscapeStringStream ES(OS, Escapes);
706-
toMustacheString(*ContextPtr, ES);
707-
}
764+
case Variable:
765+
renderVariable(CurrentCtx, OS);
708766
return;
709-
}
710-
case UnescapeVariable: {
711-
auto Lambda = Lambdas.find(AccessorValue[0]);
712-
if (Lambda != Lambdas.end()) {
713-
renderLambdas(CurrentCtx, OS, Lambda->getValue());
714-
} else if (ContextPtr) {
715-
toMustacheString(*ContextPtr, OS);
716-
}
767+
case UnescapeVariable:
768+
renderUnescapeVariable(CurrentCtx, OS);
717769
return;
718-
}
719-
case Section: {
720-
auto SectionLambda = SectionLambdas.find(AccessorValue[0]);
721-
bool IsLambda = SectionLambda != SectionLambdas.end();
722-
723-
if (IsLambda) {
724-
renderSectionLambdas(CurrentCtx, OS, SectionLambda->getValue());
725-
return;
726-
}
727-
728-
if (isContextFalsey(ContextPtr))
729-
return;
730-
731-
if (const json::Array *Arr = ContextPtr->getAsArray()) {
732-
for (const json::Value &V : *Arr)
733-
renderChild(V, OS);
734-
return;
735-
}
736-
renderChild(*ContextPtr, OS);
770+
case Section:
771+
renderSection(CurrentCtx, OS);
737772
return;
738-
}
739-
case InvertSection: {
740-
bool IsLambda = SectionLambdas.contains(AccessorValue[0]);
741-
if (isContextFalsey(ContextPtr) && !IsLambda) {
742-
// The context for the children remains unchanged from the parent's, so
743-
// we pass this node's original incoming context.
744-
renderChild(CurrentCtx, OS);
745-
}
773+
case InvertSection:
774+
renderInvertSection(CurrentCtx, OS);
746775
return;
747776
}
748-
}
749777
llvm_unreachable("Invalid ASTNode type");
750778
}
751779

0 commit comments

Comments
 (0)