#include <string>
#include <vector>
class FormatVisitor: public BaseVisitor {
public:
void Visit(const BaseNode* node) override {
node->Visit(this);
}
void Visit(const ClassDeclarationNode* node) override {
PushLine("class " + node->ClassName() + " {");
AddTab();
if (!node->PublicFields().empty()) {
PushLine("public:");
AddTab();
for (BaseNode *next_node : node->PublicFields()) {
next_node->Visit(this);
}
DelTab();
}
if (!node->ProtectedFields().empty()) {
this->data_.emplace_back("");
PushLine("protected:");
AddTab();
for (BaseNode *next_node : node->ProtectedFields()) {
next_node->Visit(this);
}
DelTab();
}
if (!node->PrivateFields().empty()) {
this->data_.emplace_back("");
PushLine("private:");
AddTab();
for (BaseNode *next_node : node->PrivateFields()) {
next_node->Visit(this);
}
DelTab();
}
DelTab();
PushLine("};");
}
void Visit(const VarDeclarationNode* node) override {
std::string line = node->TypeName() + ' ' + node->VarName();
if (this->parse_args_) {
AppendLastLine(line);
} else {
PushLine(line + ";");
}
}
void Visit(const MethodDeclarationNode* node) override {
std::string line = node->ReturnTypeName() + " ";
line += node->MethodName() + "(";
PushLine(line);
this->parse_args_ = true;
const auto &nodes = node->Arguments();
for (size_t i = 0; i < nodes.size(); ++i) {
nodes[i]->Visit(this);
if (i != nodes.size() - 1) {
AppendLastLine(", ");
}
}
this->parse_args_ = false;
AppendLastLine(");");
}
[[nodiscard]] const std::vector<std::string>& GetFormattedCode() const {
return this->data_;
}
private:
std::vector<std::string> data_;
size_t space_on_line_ = 0;
bool parse_args_ = false;
const size_t TAB_SIZE = 2;
void AddTab() {
this->space_on_line_ += TAB_SIZE;
}
void DelTab() {
this->space_on_line_ -= TAB_SIZE;
}
void PushLine(const std::string &line) {
this->data_.push_back(std::string(this->space_on_line_, ' ') + line);
}
void AppendLastLine(const std::string &str) {
this->data_.back() += str;
}
};