From 4634976626b6102cb5fc7b57af8c58c26f5eaeeb Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Fri, 27 Sep 2019 15:04:47 +0200
Subject: [PATCH] Remove empty blocks and function declarations

---
 src/language/ASTNodeDeclarationCleaner.cpp |  2 +-
 src/language/ASTNodeEmptyBlockCleaner.cpp  | 37 ++++++++++++++++++++++
 src/language/ASTNodeEmptyBlockCleaner.hpp  | 15 +++++++++
 src/language/CMakeLists.txt                |  1 +
 src/language/PugsParser.cpp                |  3 ++
 5 files changed, 57 insertions(+), 1 deletion(-)
 create mode 100644 src/language/ASTNodeEmptyBlockCleaner.cpp
 create mode 100644 src/language/ASTNodeEmptyBlockCleaner.hpp

diff --git a/src/language/ASTNodeDeclarationCleaner.cpp b/src/language/ASTNodeDeclarationCleaner.cpp
index 05a6822fd..7e2f139f9 100644
--- a/src/language/ASTNodeDeclarationCleaner.cpp
+++ b/src/language/ASTNodeDeclarationCleaner.cpp
@@ -10,7 +10,7 @@ ASTNodeDeclarationCleaner::_removeDeclarationNode(ASTNode& n)
 {
   std::stack<size_t> declaration_ids;
   for (size_t i_child = 0; i_child < n.children.size(); ++i_child) {
-    if (n.children[i_child]->is<language::declaration>()) {
+    if (n.children[i_child]->is<language::declaration>() or n.children[i_child]->is<language::let_declaration>()) {
       declaration_ids.push(i_child);
     }
   }
diff --git a/src/language/ASTNodeEmptyBlockCleaner.cpp b/src/language/ASTNodeEmptyBlockCleaner.cpp
new file mode 100644
index 000000000..eeb71c087
--- /dev/null
+++ b/src/language/ASTNodeEmptyBlockCleaner.cpp
@@ -0,0 +1,37 @@
+#include <ASTNodeEmptyBlockCleaner.hpp>
+
+#include <PEGGrammar.hpp>
+#include <PugsAssert.hpp>
+
+#include <stack>
+
+void
+ASTNodeEmptyBlockCleaner::_removeEmptyBlockNode(ASTNode& n)
+{
+  for (auto& child : n.children) {
+    this->_removeEmptyBlockNode(*child);
+  }
+
+  std::stack<size_t> empty_block_ids;
+  for (size_t i_child = 0; i_child < n.children.size(); ++i_child) {
+    if (n.children[i_child]->is<language::block>()) {
+      if (n.children[i_child]->children.size() == 0)
+        empty_block_ids.push(i_child);
+    }
+  }
+
+  while (empty_block_ids.size() > 0) {
+    size_t i_removed = empty_block_ids.top();
+    empty_block_ids.pop();
+    for (size_t i = i_removed; i + 1 < n.children.size(); ++i) {
+      n.children[i] = std::move(n.children[i + 1]);
+    }
+    n.children.pop_back();
+  }
+}
+
+ASTNodeEmptyBlockCleaner::ASTNodeEmptyBlockCleaner(ASTNode& n)
+{
+  Assert(n.is_root());
+  this->_removeEmptyBlockNode(n);
+}
diff --git a/src/language/ASTNodeEmptyBlockCleaner.hpp b/src/language/ASTNodeEmptyBlockCleaner.hpp
new file mode 100644
index 000000000..bfa492ec0
--- /dev/null
+++ b/src/language/ASTNodeEmptyBlockCleaner.hpp
@@ -0,0 +1,15 @@
+#ifndef AST_NODE_EMPTY_BLOCK_CLEANER_HPP
+#define AST_NODE_EMPTY_BLOCK_CLEANER_HPP
+
+#include <ASTNode.hpp>
+
+class ASTNodeEmptyBlockCleaner
+{
+ private:
+  void _removeEmptyBlockNode(ASTNode& node);
+
+ public:
+  ASTNodeEmptyBlockCleaner(ASTNode& root_node);
+};
+
+#endif   // AST_NODE_EMPTY_BLOCK_CLEANER_HPP
diff --git a/src/language/CMakeLists.txt b/src/language/CMakeLists.txt
index 9910dd470..ab42c18cc 100644
--- a/src/language/CMakeLists.txt
+++ b/src/language/CMakeLists.txt
@@ -16,6 +16,7 @@ add_library(
   ASTNodeDataTypeChecker.cpp
   ASTNodeDeclarationToAffectationConverter.cpp
   ASTNodeDeclarationCleaner.cpp
+  ASTNodeEmptyBlockCleaner.cpp
   ASTNodeExpressionBuilder.cpp
   ASTNodeIncDecExpressionBuilder.cpp
   ASTNodeJumpPlacementChecker.cpp
diff --git a/src/language/PugsParser.cpp b/src/language/PugsParser.cpp
index 1b40aa888..d59d53210 100644
--- a/src/language/PugsParser.cpp
+++ b/src/language/PugsParser.cpp
@@ -29,6 +29,8 @@
 #include <ASTSymbolInitializationChecker.hpp>
 #include <ASTSymbolTableBuilder.hpp>
 
+#include <ASTNodeEmptyBlockCleaner.hpp>
+
 #include <ASTNodeDeclarationCleaner.hpp>
 #include <ASTNodeDeclarationToAffectationConverter.hpp>
 
@@ -75,6 +77,7 @@ parser(const std::string& filename)
     // optimizations
     ASTNodeDeclarationToAffectationConverter{*root_node};
     ASTNodeDeclarationCleaner{*root_node};
+    ASTNodeEmptyBlockCleaner{*root_node};
 
     ASTNodeExpressionBuilder{*root_node};
 
-- 
GitLab