Skip to content

Conversation

ilovepi
Copy link
Contributor

@ilovepi ilovepi commented Sep 16, 2025

Move the rendering logic into the ASTNode, and break the logic down into
individual methods.

Copy link
Contributor Author

ilovepi commented Sep 16, 2025

@llvmbot
Copy link
Member

llvmbot commented Sep 16, 2025

@llvm/pr-subscribers-llvm-support

Author: Paul Kirth (ilovepi)

Changes

Move the rendering logic into the ASTNode, and break the logic down into
individual methods.


Full diff: https://github.com/llvm/llvm-project/pull/159189.diff

1 Files Affected:

  • (modified) llvm/lib/Support/Mustache.cpp (+92-64)
diff --git a/llvm/lib/Support/Mustache.cpp b/llvm/lib/Support/Mustache.cpp
index 08317a7b98902..e2de7645e8dfb 100644
--- a/llvm/lib/Support/Mustache.cpp
+++ b/llvm/lib/Support/Mustache.cpp
@@ -181,6 +181,14 @@ class ASTNode {
 
   const llvm::json::Value *findContext();
 
+  void renderRoot(const json::Value &CurrentCtx, raw_ostream &OS);
+  void renderText(raw_ostream &OS);
+  void renderPartial(const json::Value &CurrentCtx, raw_ostream &OS);
+  void renderVariable(const json::Value &CurrentCtx, raw_ostream &OS);
+  void renderUnescapeVariable(const json::Value &CurrentCtx, raw_ostream &OS);
+  void renderSection(const json::Value &CurrentCtx, raw_ostream &OS);
+  void renderInvertSection(const json::Value &CurrentCtx, raw_ostream &OS);
+
   StringMap<AstPtr> &Partials;
   StringMap<Lambda> &Lambdas;
   StringMap<SectionLambda> &SectionLambdas;
@@ -198,26 +206,26 @@ class ASTNode {
 
 // A wrapper for arena allocator for ASTNodes
 static AstPtr createRootNode(llvm::StringMap<AstPtr> &Partials,
-                      llvm::StringMap<Lambda> &Lambdas,
-                      llvm::StringMap<SectionLambda> &SectionLambdas,
-                      EscapeMap &Escapes) {
+                             llvm::StringMap<Lambda> &Lambdas,
+                             llvm::StringMap<SectionLambda> &SectionLambdas,
+                             EscapeMap &Escapes) {
   return std::make_unique<ASTNode>(Partials, Lambdas, SectionLambdas, Escapes);
 }
 
 static AstPtr createNode(ASTNode::Type T, Accessor A, ASTNode *Parent,
-                  llvm::StringMap<AstPtr> &Partials,
-                  llvm::StringMap<Lambda> &Lambdas,
-                  llvm::StringMap<SectionLambda> &SectionLambdas,
-                  EscapeMap &Escapes) {
+                         llvm::StringMap<AstPtr> &Partials,
+                         llvm::StringMap<Lambda> &Lambdas,
+                         llvm::StringMap<SectionLambda> &SectionLambdas,
+                         EscapeMap &Escapes) {
   return std::make_unique<ASTNode>(T, std::move(A), Parent, Partials, Lambdas,
                                    SectionLambdas, Escapes);
 }
 
 static AstPtr createTextNode(std::string Body, ASTNode *Parent,
-                      llvm::StringMap<AstPtr> &Partials,
-                      llvm::StringMap<Lambda> &Lambdas,
-                      llvm::StringMap<SectionLambda> &SectionLambdas,
-                      EscapeMap &Escapes) {
+                             llvm::StringMap<AstPtr> &Partials,
+                             llvm::StringMap<Lambda> &Lambdas,
+                             llvm::StringMap<SectionLambda> &SectionLambdas,
+                             EscapeMap &Escapes) {
   return std::make_unique<ASTNode>(std::move(Body), Parent, Partials, Lambdas,
                                    SectionLambdas, Escapes);
 }
@@ -295,7 +303,7 @@ static void stripTokenAhead(SmallVectorImpl<Token> &Tokens, size_t Idx) {
 // The exception for this is partial tag which requires us to
 // keep track of the indentation once it's rendered.
 static void stripTokenBefore(SmallVectorImpl<Token> &Tokens, size_t Idx,
-                      Token &CurrentToken, Token::Type CurrentType) {
+                             Token &CurrentToken, Token::Type CurrentType) {
   Token &PrevToken = Tokens[Idx - 1];
   StringRef PrevTokenBody = PrevToken.TokenBody;
   StringRef Unindented = PrevTokenBody.rtrim(" \r\t\v");
@@ -676,76 +684,96 @@ static void toMustacheString(const json::Value &Data, raw_ostream &OS) {
   }
 }
 
+void ASTNode::renderRoot(const json::Value &CurrentCtx, raw_ostream &OS) {
+  renderChild(CurrentCtx, OS);
+}
+
+void ASTNode::renderText(raw_ostream &OS) { OS << Body; }
+
+void ASTNode::renderPartial(const json::Value &CurrentCtx, raw_ostream &OS) {
+  auto Partial = Partials.find(AccessorValue[0]);
+  if (Partial != Partials.end())
+    renderPartial(CurrentCtx, OS, Partial->getValue().get());
+}
+
+void ASTNode::renderVariable(const json::Value &CurrentCtx, raw_ostream &OS) {
+  auto Lambda = Lambdas.find(AccessorValue[0]);
+  if (Lambda != Lambdas.end()) {
+    renderLambdas(CurrentCtx, OS, Lambda->getValue());
+  } else if (const json::Value *ContextPtr = findContext()) {
+    EscapeStringStream ES(OS, Escapes);
+    toMustacheString(*ContextPtr, ES);
+  }
+}
+
+void ASTNode::renderUnescapeVariable(const json::Value &CurrentCtx,
+                                     raw_ostream &OS) {
+  auto Lambda = Lambdas.find(AccessorValue[0]);
+  if (Lambda != Lambdas.end()) {
+    renderLambdas(CurrentCtx, OS, Lambda->getValue());
+  } else if (const json::Value *ContextPtr = findContext()) {
+    toMustacheString(*ContextPtr, OS);
+  }
+}
+
+void ASTNode::renderSection(const json::Value &CurrentCtx, raw_ostream &OS) {
+  auto SectionLambda = SectionLambdas.find(AccessorValue[0]);
+  if (SectionLambda != SectionLambdas.end()) {
+    renderSectionLambdas(CurrentCtx, OS, SectionLambda->getValue());
+    return;
+  }
+
+  const json::Value *ContextPtr = findContext();
+  if (isContextFalsey(ContextPtr))
+    return;
+
+  if (const json::Array *Arr = ContextPtr->getAsArray()) {
+    for (const json::Value &V : *Arr)
+      renderChild(V, OS);
+    return;
+  }
+  renderChild(*ContextPtr, OS);
+}
+
+void ASTNode::renderInvertSection(const json::Value &CurrentCtx,
+                                  raw_ostream &OS) {
+  bool IsLambda = SectionLambdas.contains(AccessorValue[0]);
+  const json::Value *ContextPtr = findContext();
+  if (isContextFalsey(ContextPtr) && !IsLambda) {
+    renderChild(CurrentCtx, OS);
+  }
+}
+
 void ASTNode::render(const json::Value &CurrentCtx, raw_ostream &OS) {
   if (Ty != Root && Ty != Text && AccessorValue.empty())
     return;
   // Set the parent context to the incoming context so that we
   // can walk up the context tree correctly in findContext().
   ParentContext = &CurrentCtx;
-  const json::Value *ContextPtr = Ty == Root ? ParentContext : findContext();
 
   switch (Ty) {
   case Root:
-    renderChild(CurrentCtx, OS);
+    renderRoot(CurrentCtx, OS);
     return;
   case Text:
-    OS << Body;
+    renderText(OS);
     return;
-  case Partial: {
-    auto Partial = Partials.find(AccessorValue[0]);
-    if (Partial != Partials.end())
-      renderPartial(CurrentCtx, OS, Partial->getValue().get());
+  case Partial:
+    renderPartial(CurrentCtx, OS);
     return;
-  }
-  case Variable: {
-    auto Lambda = Lambdas.find(AccessorValue[0]);
-    if (Lambda != Lambdas.end()) {
-      renderLambdas(CurrentCtx, OS, Lambda->getValue());
-    } else if (ContextPtr) {
-      EscapeStringStream ES(OS, Escapes);
-      toMustacheString(*ContextPtr, ES);
-    }
+  case Variable:
+    renderVariable(CurrentCtx, OS);
     return;
-  }
-  case UnescapeVariable: {
-    auto Lambda = Lambdas.find(AccessorValue[0]);
-    if (Lambda != Lambdas.end()) {
-      renderLambdas(CurrentCtx, OS, Lambda->getValue());
-    } else if (ContextPtr) {
-      toMustacheString(*ContextPtr, OS);
-    }
+  case UnescapeVariable:
+    renderUnescapeVariable(CurrentCtx, OS);
     return;
-  }
-  case Section: {
-    auto SectionLambda = SectionLambdas.find(AccessorValue[0]);
-    bool IsLambda = SectionLambda != SectionLambdas.end();
-
-    if (IsLambda) {
-      renderSectionLambdas(CurrentCtx, OS, SectionLambda->getValue());
-      return;
-    }
-
-    if (isContextFalsey(ContextPtr))
-      return;
-
-    if (const json::Array *Arr = ContextPtr->getAsArray()) {
-      for (const json::Value &V : *Arr)
-        renderChild(V, OS);
-      return;
-    }
-    renderChild(*ContextPtr, OS);
+  case Section:
+    renderSection(CurrentCtx, OS);
     return;
-  }
-  case InvertSection: {
-    bool IsLambda = SectionLambdas.contains(AccessorValue[0]);
-    if (isContextFalsey(ContextPtr) && !IsLambda) {
-      // The context for the children remains unchanged from the parent's, so
-      // we pass this node's original incoming context.
-      renderChild(CurrentCtx, OS);
-    }
+  case InvertSection:
+    renderInvertSection(CurrentCtx, OS);
     return;
   }
-  }
   llvm_unreachable("Invalid ASTNode type");
 }
 

@ilovepi ilovepi force-pushed the users/ilovepi/mustache-tokenizer branch from c8b70b1 to 6f78e4d Compare September 22, 2025 17:07
@ilovepi ilovepi force-pushed the users/ilovepi/mustache-renderer branch from 8175095 to 61bcc58 Compare September 22, 2025 17:07
@ilovepi ilovepi force-pushed the users/ilovepi/mustache-tokenizer branch from 6f78e4d to 97182cf Compare September 22, 2025 17:56
@ilovepi ilovepi force-pushed the users/ilovepi/mustache-renderer branch from 61bcc58 to 6a7db43 Compare September 22, 2025 17:56
@ilovepi ilovepi force-pushed the users/ilovepi/mustache-tokenizer branch from 97182cf to 7a0b305 Compare September 25, 2025 22:12
@ilovepi ilovepi force-pushed the users/ilovepi/mustache-renderer branch from 6a7db43 to 3d00de1 Compare September 25, 2025 22:12
@ilovepi ilovepi force-pushed the users/ilovepi/mustache-tokenizer branch from 7a0b305 to 8be25f4 Compare September 26, 2025 01:55
@ilovepi ilovepi force-pushed the users/ilovepi/mustache-renderer branch from 3d00de1 to f18412d Compare September 26, 2025 01:55
@ilovepi ilovepi force-pushed the users/ilovepi/mustache-tokenizer branch from 8be25f4 to 289f098 Compare September 29, 2025 17:39
@ilovepi ilovepi force-pushed the users/ilovepi/mustache-renderer branch 2 times, most recently from 7ca57bb to af8b255 Compare September 29, 2025 22:28
@ilovepi ilovepi force-pushed the users/ilovepi/mustache-tokenizer branch from 289f098 to 41ea349 Compare September 29, 2025 22:28
Copy link
Contributor Author

ilovepi commented Sep 29, 2025

Merge activity

  • Sep 29, 11:30 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Sep 30, 12:55 AM UTC: Graphite rebased this pull request as part of a merge.
  • Sep 30, 1:22 AM UTC: Graphite rebased this pull request as part of a merge.

@ilovepi ilovepi force-pushed the users/ilovepi/mustache-tokenizer branch 2 times, most recently from 457c8d5 to 0693f63 Compare September 30, 2025 00:27
Base automatically changed from users/ilovepi/mustache-tokenizer to main September 30, 2025 00:55
@ilovepi ilovepi force-pushed the users/ilovepi/mustache-renderer branch from af8b255 to 26f0197 Compare September 30, 2025 00:55
Move the rendering logic into the ASTNode, and break the logic down into
individual methods.
@ilovepi ilovepi force-pushed the users/ilovepi/mustache-renderer branch from 26f0197 to 16f12ac Compare September 30, 2025 01:22
@ilovepi ilovepi enabled auto-merge (squash) September 30, 2025 01:23
@ilovepi ilovepi merged commit 781baf7 into main Sep 30, 2025
9 checks passed
@ilovepi ilovepi deleted the users/ilovepi/mustache-renderer branch September 30, 2025 01:48
mahesh-attarde pushed a commit to mahesh-attarde/llvm-project that referenced this pull request Oct 3, 2025
Move the rendering logic into the ASTNode, and break the logic down into
individual methods.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants