1702 lines
48 KiB
C++
1702 lines
48 KiB
C++
#include <sstream>
|
|
#include <algorithm>
|
|
#include "./debug_printer.hpp"
|
|
|
|
namespace lsp::language::ast
|
|
{
|
|
// ===== 便捷函数实现 =====
|
|
|
|
std::string DebugString(const ASTNode* node, const PrintOptions& opts)
|
|
{
|
|
std::ostringstream oss;
|
|
DebugPrinter printer(oss, opts);
|
|
if (node)
|
|
{
|
|
printer.Print(node);
|
|
}
|
|
return oss.str();
|
|
}
|
|
|
|
std::string DebugString(const ParseResult& result, const PrintOptions& opts)
|
|
{
|
|
std::ostringstream oss;
|
|
DebugPrinter printer(oss, opts);
|
|
printer.PrintParseResult(result);
|
|
return oss.str();
|
|
}
|
|
|
|
void DebugPrint(const ASTNode* node, const PrintOptions& opts)
|
|
{
|
|
DebugPrinter printer(std::cout, opts);
|
|
if (node)
|
|
{
|
|
printer.Print(node);
|
|
}
|
|
}
|
|
|
|
void DebugPrint(const ParseResult& result, const PrintOptions& opts)
|
|
{
|
|
DebugPrinter printer(std::cout, opts);
|
|
printer.PrintParseResult(result);
|
|
}
|
|
|
|
void DebugPrint(const ASTNode* node, const std::string& source, const PrintOptions& opts)
|
|
{
|
|
DebugPrinter printer(std::cout, opts);
|
|
printer.SetSourceCode(&source);
|
|
if (node)
|
|
{
|
|
printer.Print(node);
|
|
}
|
|
}
|
|
|
|
void DebugPrint(const ParseResult& result, const std::string& source, const PrintOptions& opts)
|
|
{
|
|
DebugPrinter printer(std::cout, opts);
|
|
printer.SetSourceCode(&source);
|
|
printer.PrintParseResult(result);
|
|
}
|
|
|
|
// ===== DebugPrinter 主要方法 =====
|
|
|
|
void DebugPrinter::Print(const ASTNode* node)
|
|
{
|
|
if (!node)
|
|
{
|
|
os_ << GetColor(Color::Red) << "nullptr" << GetColor(Color::Reset) << "\n";
|
|
return;
|
|
}
|
|
|
|
const_cast<ASTNode*>(node)->Accept(*this);
|
|
}
|
|
|
|
void DebugPrinter::PrintStatements(const std::vector<StatementPtr>& statements)
|
|
{
|
|
if (statements.empty())
|
|
{
|
|
PrintColored("(empty)", Color::Gray);
|
|
os_ << "\n";
|
|
return;
|
|
}
|
|
|
|
for (size_t i = 0; i < statements.size(); ++i)
|
|
{
|
|
bool is_last = (i == statements.size() - 1);
|
|
PrintStatement(statements[i].get(), "", is_last);
|
|
}
|
|
}
|
|
|
|
void DebugPrinter::PrintParseResult(const ParseResult& result)
|
|
{
|
|
PrintColored("=== Parse Result ===", Color::BrightCyan);
|
|
os_ << "\n\n";
|
|
|
|
if (result.root)
|
|
{
|
|
Print(result.root.get());
|
|
}
|
|
else
|
|
{
|
|
PrintColored("No root node", Color::Red);
|
|
os_ << "\n";
|
|
}
|
|
|
|
if (!result.errors.empty())
|
|
{
|
|
os_ << "\n";
|
|
PrintColored("=== Errors ===", Color::BrightRed);
|
|
os_ << "\n";
|
|
for (const auto& error : result.errors)
|
|
{
|
|
PrintError(error);
|
|
}
|
|
}
|
|
}
|
|
|
|
// ===== 辅助方法实现 =====
|
|
|
|
void DebugPrinter::PrintIndent(bool is_last)
|
|
{
|
|
if (!options_.use_tree_chars)
|
|
{
|
|
os_ << std::string(current_indent_, ' ');
|
|
return;
|
|
}
|
|
|
|
PrintTreePrefix(is_last);
|
|
}
|
|
|
|
void DebugPrinter::PrintTreePrefix(bool is_last)
|
|
{
|
|
int depth = current_indent_ / options_.indent_size;
|
|
for (int i = 0; i < depth - 1; ++i)
|
|
{
|
|
if (i < static_cast<int>(is_last_child_stack_.size()) && is_last_child_stack_[i])
|
|
{
|
|
os_ << " ";
|
|
}
|
|
else
|
|
{
|
|
os_ << "│ ";
|
|
}
|
|
}
|
|
|
|
if (depth > 0)
|
|
{
|
|
if (is_last)
|
|
{
|
|
os_ << "└── ";
|
|
}
|
|
else
|
|
{
|
|
os_ << "├── ";
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string DebugPrinter::GetIndent() const
|
|
{
|
|
return std::string(current_indent_, ' ');
|
|
}
|
|
|
|
const char* DebugPrinter::GetColor(const char* color) const
|
|
{
|
|
return options_.use_colors ? color : "";
|
|
}
|
|
|
|
void DebugPrinter::PrintColored(const std::string& text, const char* color)
|
|
{
|
|
if (color)
|
|
{
|
|
os_ << GetColor(color);
|
|
}
|
|
os_ << text;
|
|
if (color)
|
|
{
|
|
os_ << GetColor(Color::Reset);
|
|
}
|
|
}
|
|
|
|
void DebugPrinter::PrintNodeHeader(const std::string& type_name, const Location& loc)
|
|
{
|
|
PrintColored(type_name, Color::BrightYellow);
|
|
|
|
if (options_.show_location)
|
|
{
|
|
os_ << " ";
|
|
PrintLocation(loc);
|
|
}
|
|
|
|
if (options_.show_source_code && source_code_)
|
|
{
|
|
os_ << " ";
|
|
PrintSourceSnippet(loc);
|
|
}
|
|
|
|
os_ << "\n";
|
|
}
|
|
|
|
void DebugPrinter::PrintLocation(const Location& loc)
|
|
{
|
|
os_ << GetColor(Color::Gray) << "@"
|
|
<< loc.start_line << ":" << loc.start_column
|
|
<< "-" << loc.end_line << ":" << loc.end_column
|
|
<< GetColor(Color::Reset);
|
|
}
|
|
|
|
void DebugPrinter::PrintSourceSnippet(const Location& loc)
|
|
{
|
|
if (!source_code_ || loc.start_byte >= source_code_->length())
|
|
{
|
|
return;
|
|
}
|
|
|
|
std::string snippet = GetSourceText(loc);
|
|
snippet = TruncateString(snippet, options_.max_source_length);
|
|
snippet = EscapeString(snippet);
|
|
|
|
os_ << GetColor(Color::Cyan) << "«" << snippet << "»" << GetColor(Color::Reset);
|
|
}
|
|
|
|
void DebugPrinter::PrintKeyValue(const std::string& key, const std::string& value,
|
|
const Location& location, const char* value_color)
|
|
{
|
|
PrintIndent();
|
|
PrintColored(key, Color::Green);
|
|
os_ << ": ";
|
|
PrintColored(value, value_color);
|
|
|
|
if (options_.show_location)
|
|
{
|
|
os_ << " ";
|
|
PrintLocation(location);
|
|
}
|
|
|
|
os_ << "\n";
|
|
}
|
|
|
|
void DebugPrinter::PrintKeyValue(const std::string& key, const std::string& value, const char* value_color)
|
|
{
|
|
PrintIndent();
|
|
PrintColored(key, Color::Green);
|
|
os_ << ": ";
|
|
PrintColored(value, value_color);
|
|
os_ << "\n";
|
|
}
|
|
|
|
void DebugPrinter::PrintKeyValue(const std::string& key, int value)
|
|
{
|
|
PrintIndent();
|
|
PrintColored(key, Color::Green);
|
|
os_ << ": ";
|
|
PrintColored(std::to_string(value), Color::BrightMagenta);
|
|
os_ << "\n";
|
|
}
|
|
|
|
void DebugPrinter::PrintKeyValue(const std::string& key, bool value)
|
|
{
|
|
PrintIndent();
|
|
PrintColored(key, Color::Green);
|
|
os_ << ": ";
|
|
PrintColored(value ? "true" : "false", Color::BrightMagenta);
|
|
os_ << "\n";
|
|
}
|
|
|
|
void DebugPrinter::PrintExpression(const Expression* expr, const std::string& label, bool is_last)
|
|
{
|
|
if (!expr)
|
|
{
|
|
PrintIndent(is_last);
|
|
if (!label.empty())
|
|
{
|
|
PrintColored(label, Color::Green);
|
|
os_ << ": ";
|
|
}
|
|
PrintColored("nullptr", Color::Red);
|
|
os_ << "\n";
|
|
return;
|
|
}
|
|
|
|
if (!label.empty())
|
|
{
|
|
PrintIndent(is_last);
|
|
PrintColored(label, Color::Green);
|
|
os_ << ":\n";
|
|
|
|
is_last_child_stack_.push_back(is_last);
|
|
IncreaseIndent();
|
|
}
|
|
|
|
const_cast<Expression*>(expr)->Accept(*this);
|
|
|
|
if (!label.empty())
|
|
{
|
|
DecreaseIndent();
|
|
is_last_child_stack_.pop_back();
|
|
}
|
|
}
|
|
|
|
void DebugPrinter::PrintStatement(const Statement* stmt, const std::string& label, bool is_last)
|
|
{
|
|
if (!stmt)
|
|
{
|
|
PrintIndent(is_last);
|
|
if (!label.empty())
|
|
{
|
|
PrintColored(label, Color::Green);
|
|
os_ << ": ";
|
|
}
|
|
PrintColored("nullptr", Color::Red);
|
|
os_ << "\n";
|
|
return;
|
|
}
|
|
|
|
if (!label.empty())
|
|
{
|
|
PrintIndent(is_last);
|
|
PrintColored(label, Color::Green);
|
|
os_ << ":\n";
|
|
|
|
is_last_child_stack_.push_back(is_last);
|
|
IncreaseIndent();
|
|
}
|
|
|
|
const_cast<Statement*>(stmt)->Accept(*this);
|
|
|
|
if (!label.empty())
|
|
{
|
|
DecreaseIndent();
|
|
is_last_child_stack_.pop_back();
|
|
}
|
|
}
|
|
|
|
void DebugPrinter::PrintSignature(const Signature& sig)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("signature", Color::Green);
|
|
os_ << ":\n";
|
|
|
|
IncreaseIndent();
|
|
|
|
if (!sig.parameters.empty())
|
|
{
|
|
PrintIndent();
|
|
PrintColored("parameters", Color::Green);
|
|
os_ << ":\n";
|
|
|
|
IncreaseIndent();
|
|
for (size_t i = 0; i < sig.parameters.size(); ++i)
|
|
{
|
|
bool is_last = (i == sig.parameters.size() - 1);
|
|
PrintParameter(sig.parameters[i], is_last);
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
|
|
if (sig.return_type)
|
|
PrintKeyValue("return_type", sig.return_type->name, sig.return_type->location, Color::BrightBlue);
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::PrintParameter(const Parameter& param, bool is_last)
|
|
{
|
|
PrintIndent(is_last);
|
|
PrintColored("param", Color::Yellow);
|
|
os_ << " ";
|
|
PrintColored(param.name, Color::BrightCyan);
|
|
|
|
if (param.type)
|
|
{
|
|
os_ << ": ";
|
|
PrintColored(param.type->name, Color::BrightBlue);
|
|
}
|
|
|
|
if (param.is_var)
|
|
os_ << " " << GetColor(Color::Magenta) << "[var]" << GetColor(Color::Reset);
|
|
|
|
if (param.is_out)
|
|
os_ << " " << GetColor(Color::Magenta) << "[out]" << GetColor(Color::Reset);
|
|
|
|
if (options_.show_location)
|
|
{
|
|
os_ << " ";
|
|
PrintLocation(param.location);
|
|
}
|
|
|
|
os_ << "\n";
|
|
|
|
if (param.default_value)
|
|
{
|
|
is_last_child_stack_.push_back(is_last);
|
|
IncreaseIndent();
|
|
PrintExpression(param.default_value.get(), "default", true);
|
|
DecreaseIndent();
|
|
is_last_child_stack_.pop_back();
|
|
}
|
|
}
|
|
|
|
void DebugPrinter::PrintLeftHandSide(const LeftHandSide& lhs, const std::string& label, bool is_last)
|
|
{
|
|
if (!label.empty())
|
|
{
|
|
PrintIndent(is_last);
|
|
PrintColored(label, Color::Green);
|
|
os_ << ":\n";
|
|
|
|
is_last_child_stack_.push_back(is_last);
|
|
IncreaseIndent();
|
|
}
|
|
|
|
std::visit([this](auto&& arg) {
|
|
if (arg)
|
|
{
|
|
arg->Accept(*this);
|
|
}
|
|
else
|
|
{
|
|
PrintIndent();
|
|
PrintColored("nullptr", Color::Red);
|
|
os_ << "\n";
|
|
}
|
|
}, lhs);
|
|
|
|
if (!label.empty())
|
|
{
|
|
DecreaseIndent();
|
|
is_last_child_stack_.pop_back();
|
|
}
|
|
}
|
|
|
|
void DebugPrinter::PrintOperator(BinaryOperator op)
|
|
{
|
|
os_ << GetColor(Color::BrightYellow) << GetBinaryOperatorSymbol(op) << GetColor(Color::Reset);
|
|
}
|
|
|
|
void DebugPrinter::PrintOperator(UnaryOperator op)
|
|
{
|
|
std::string symbol;
|
|
switch (op)
|
|
{
|
|
case UnaryOperator::kPlus: symbol = "+"; break;
|
|
case UnaryOperator::kMinus: symbol = "-"; break;
|
|
case UnaryOperator::kNot: symbol = "not"; break;
|
|
case UnaryOperator::kBitwiseNot: symbol = "~"; break;
|
|
case UnaryOperator::kDotNot: symbol = ".not"; break;
|
|
case UnaryOperator::kMatrixTranspose: symbol = "'"; break;
|
|
case UnaryOperator::kDerivative: symbol = "∂"; break;
|
|
case UnaryOperator::kExprAt: symbol = "@"; break;
|
|
case UnaryOperator::kExprRef: symbol = "&"; break;
|
|
default: symbol = "unknown"; break;
|
|
}
|
|
os_ << GetColor(Color::BrightYellow) << symbol << GetColor(Color::Reset);
|
|
}
|
|
|
|
void DebugPrinter::PrintOperator(AssignmentOperator op)
|
|
{
|
|
os_ << GetColor(Color::BrightYellow) << GetAssignmentOperatorSymbol(op) << GetColor(Color::Reset);
|
|
}
|
|
|
|
void DebugPrinter::PrintLiteralKind(LiteralKind kind)
|
|
{
|
|
std::string kind_str;
|
|
const char* color = Color::Cyan;
|
|
|
|
switch (kind)
|
|
{
|
|
case LiteralKind::kNumber: kind_str = "number"; color = Color::BrightMagenta; break;
|
|
case LiteralKind::kString: kind_str = "string"; color = Color::BrightGreen; break;
|
|
case LiteralKind::kBoolean: kind_str = "boolean"; color = Color::BrightBlue; break;
|
|
case LiteralKind::kNil: kind_str = "nil"; color = Color::Gray; break;
|
|
case LiteralKind::kInfinity: kind_str = "infinity"; color = Color::BrightMagenta; break;
|
|
case LiteralKind::kEllipsis: kind_str = "ellipsis"; color = Color::Gray; break;
|
|
default: kind_str = "unknown"; break;
|
|
}
|
|
|
|
PrintColored(kind_str, color);
|
|
}
|
|
|
|
void DebugPrinter::PrintAccessModifier(AccessModifier modifier)
|
|
{
|
|
std::string mod_str;
|
|
switch (modifier)
|
|
{
|
|
case AccessModifier::kPublic: mod_str = "public"; break;
|
|
case AccessModifier::kProtected: mod_str = "protected"; break;
|
|
case AccessModifier::kPrivate: mod_str = "private"; break;
|
|
default: mod_str = "unknown"; break;
|
|
}
|
|
PrintColored(mod_str, Color::Magenta);
|
|
}
|
|
|
|
void DebugPrinter::PrintMethodModifier(MethodModifier modifier)
|
|
{
|
|
std::string mod_str;
|
|
switch (modifier)
|
|
{
|
|
case MethodModifier::kNone: return;
|
|
case MethodModifier::kVirtual: mod_str = "virtual"; break;
|
|
case MethodModifier::kOverride: mod_str = "override"; break;
|
|
case MethodModifier::kOverload: mod_str = "overload"; break;
|
|
default: mod_str = "unknown"; break;
|
|
}
|
|
os_ << " " << GetColor(Color::Magenta) << "[" << mod_str << "]" << GetColor(Color::Reset);
|
|
}
|
|
|
|
void DebugPrinter::PrintReferenceModifier(ReferenceModifier modifier)
|
|
{
|
|
std::string mod_str;
|
|
switch (modifier)
|
|
{
|
|
case ReferenceModifier::kNone: return;
|
|
case ReferenceModifier::kWeakRef: mod_str = "weakref"; break;
|
|
case ReferenceModifier::kAutoRef: mod_str = "autoref"; break;
|
|
default: mod_str = "unknown"; break;
|
|
}
|
|
os_ << " " << GetColor(Color::Magenta) << "[" << mod_str << "]" << GetColor(Color::Reset);
|
|
}
|
|
|
|
void DebugPrinter::PrintError(const ParseError& error)
|
|
{
|
|
const char* severity_color = (error.severity == ErrorSeverity::Error) ? Color::BrightRed : Color::BrightYellow;
|
|
const char* severity_str = (error.severity == ErrorSeverity::Error) ? "Error" : "Warning";
|
|
|
|
PrintColored(severity_str, severity_color);
|
|
os_ << " at ";
|
|
PrintLocation(error.location);
|
|
os_ << " in " << GetColor(Color::Yellow) << error.node_type << GetColor(Color::Reset);
|
|
os_ << ": " << error.message << "\n";
|
|
|
|
if (options_.show_source_code && source_code_)
|
|
{
|
|
os_ << " ";
|
|
PrintSourceSnippet(error.location);
|
|
os_ << "\n";
|
|
}
|
|
}
|
|
|
|
std::string DebugPrinter::EscapeString(const std::string& str) const
|
|
{
|
|
std::string result;
|
|
result.reserve(str.length());
|
|
for (char c : str)
|
|
{
|
|
switch (c)
|
|
{
|
|
case '\n': result += "\\n"; break;
|
|
case '\r': result += "\\r"; break;
|
|
case '\t': result += "\\t"; break;
|
|
case '\\': result += "\\\\"; break;
|
|
default: result += c; break;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
std::string DebugPrinter::TruncateString(const std::string& str, size_t max_len) const
|
|
{
|
|
if (str.length() <= max_len)
|
|
{
|
|
return str;
|
|
}
|
|
return str.substr(0, max_len) + "...";
|
|
}
|
|
|
|
std::string DebugPrinter::GetSourceText(const Location& loc) const
|
|
{
|
|
if (!source_code_ || loc.start_byte >= source_code_->length())
|
|
{
|
|
return "";
|
|
}
|
|
|
|
size_t end = std::min(loc.end_byte, static_cast<uint32_t>(source_code_->length()));
|
|
return source_code_->substr(loc.start_byte, end - loc.start_byte);
|
|
}
|
|
|
|
// ===== Visitor 方法实现 =====
|
|
|
|
void DebugPrinter::VisitProgram(Program& node)
|
|
{
|
|
PrintIndent();
|
|
PrintNodeHeader("Program", node.span);
|
|
|
|
IncreaseIndent();
|
|
PrintStatements(node.statements);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitUnitDefinition(UnitDefinition& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("UnitDefinition", Color::BrightYellow);
|
|
os_ << " " << GetColor(Color::BrightCyan) << node.name << GetColor(Color::Reset);
|
|
if (options_.show_location)
|
|
{
|
|
os_ << " ";
|
|
PrintLocation(node.location);
|
|
}
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
|
|
if (!node.interface_statements.empty())
|
|
{
|
|
PrintIndent();
|
|
PrintColored("interface", Color::Green);
|
|
os_ << ":\n";
|
|
|
|
IncreaseIndent();
|
|
PrintStatements(node.interface_statements);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
if (!node.implementation_statements.empty())
|
|
{
|
|
PrintIndent();
|
|
PrintColored("implementation", Color::Green);
|
|
os_ << ":\n";
|
|
|
|
IncreaseIndent();
|
|
PrintStatements(node.implementation_statements);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
if (!node.initialization_statements.empty())
|
|
{
|
|
PrintIndent();
|
|
PrintColored("initialization", Color::Green);
|
|
os_ << ":\n";
|
|
|
|
IncreaseIndent();
|
|
PrintStatements(node.initialization_statements);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
if (!node.finalization_statements.empty())
|
|
{
|
|
PrintIndent();
|
|
PrintColored("finalization", Color::Green);
|
|
os_ << ":\n";
|
|
|
|
IncreaseIndent();
|
|
PrintStatements(node.finalization_statements);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitClassDefinition(ClassDefinition& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("ClassDefinition", Color::BrightYellow);
|
|
os_ << " " << GetColor(Color::BrightCyan) << node.name << GetColor(Color::Reset);
|
|
if (options_.show_location)
|
|
{
|
|
os_ << " ";
|
|
PrintLocation(node.location);
|
|
}
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
|
|
if (!node.parent_classes.empty())
|
|
{
|
|
PrintIndent();
|
|
PrintColored("inherits", Color::Green);
|
|
os_ << ": ";
|
|
for (size_t i = 0; i < node.parent_classes.size(); ++i)
|
|
{
|
|
const auto& parent = node.parent_classes[i];
|
|
if (i > 0) os_ << ", ";
|
|
|
|
if (parent.qualifier)
|
|
{
|
|
PrintColored(*parent.qualifier, Color::BrightBlue);
|
|
os_ << ".";
|
|
}
|
|
PrintColored(parent.name, Color::BrightCyan);
|
|
}
|
|
os_ << "\n";
|
|
}
|
|
|
|
if (!node.members.empty())
|
|
{
|
|
PrintIndent();
|
|
PrintColored("members", Color::Green);
|
|
os_ << ":\n";
|
|
|
|
IncreaseIndent();
|
|
for (size_t i = 0; i < node.members.size(); ++i)
|
|
{
|
|
bool is_last = (i == node.members.size() - 1);
|
|
is_last_child_stack_.push_back(is_last);
|
|
node.members[i]->Accept(*this);
|
|
is_last_child_stack_.pop_back();
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitClassMember(ClassMember& node)
|
|
{
|
|
PrintIndent(!is_last_child_stack_.empty() ? is_last_child_stack_.back() : false);
|
|
PrintColored("[", Color::Gray);
|
|
PrintAccessModifier(node.access_modifier);
|
|
PrintColored("]", Color::Gray);
|
|
os_ << " ";
|
|
|
|
std::visit([this](auto&& arg) {
|
|
if (arg)
|
|
{
|
|
// Don't print indent again since we already did
|
|
int saved_indent = current_indent_;
|
|
current_indent_ = 0;
|
|
arg->Accept(*this);
|
|
current_indent_ = saved_indent;
|
|
}
|
|
}, node.member);
|
|
}
|
|
|
|
void DebugPrinter::VisitMethodDeclaration(MethodDeclaration& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("MethodDeclaration", Color::BrightYellow);
|
|
os_ << " " << GetColor(Color::BrightCyan) << node.name << GetColor(Color::Reset);
|
|
PrintMethodModifier(node.modifier);
|
|
|
|
if (node.is_class_method)
|
|
{
|
|
os_ << " " << GetColor(Color::Magenta) << "[class]" << GetColor(Color::Reset);
|
|
}
|
|
|
|
if (node.is_operator_overload)
|
|
{
|
|
os_ << " " << GetColor(Color::Magenta) << "[operator]" << GetColor(Color::Reset);
|
|
}
|
|
|
|
if (options_.show_location)
|
|
{
|
|
os_ << " ";
|
|
PrintLocation(node.location);
|
|
}
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
PrintSignature(node.signature);
|
|
if (node.body)
|
|
{
|
|
PrintStatement(node.body.get(), "body", true);
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitPropertyDeclaration(PropertyDeclaration& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("PropertyDeclaration", Color::BrightYellow);
|
|
os_ << " " << GetColor(Color::BrightCyan) << node.name << GetColor(Color::Reset);
|
|
if (options_.show_location)
|
|
{
|
|
os_ << " ";
|
|
PrintLocation(node.location);
|
|
}
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
|
|
if (node.type_name)
|
|
{
|
|
PrintKeyValue("type", *node.type_name, Color::BrightBlue);
|
|
}
|
|
|
|
if (node.index_value)
|
|
{
|
|
PrintKeyValue("index", *node.index_value);
|
|
}
|
|
|
|
if (node.read_accessor)
|
|
{
|
|
PrintKeyValue("read", *node.read_accessor);
|
|
}
|
|
|
|
if (node.write_accessor)
|
|
{
|
|
PrintKeyValue("write", *node.write_accessor);
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitExternalMethodDefinition(ExternalMethodDefinition& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("ExternalMethodDefinition", Color::BrightYellow);
|
|
os_ << " " << GetColor(Color::BrightBlue) << node.owner_class.name << GetColor(Color::Reset);
|
|
os_ << "." << GetColor(Color::BrightCyan) << node.name << GetColor(Color::Reset);
|
|
PrintMethodModifier(node.modifier);
|
|
|
|
if (node.is_class_method)
|
|
{
|
|
os_ << " " << GetColor(Color::Magenta) << "[class]" << GetColor(Color::Reset);
|
|
}
|
|
|
|
if (options_.show_location)
|
|
{
|
|
os_ << " ";
|
|
PrintLocation(node.location);
|
|
}
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
PrintSignature(node.signature);
|
|
if (node.body)
|
|
{
|
|
PrintStatement(node.body.get(), "body", true);
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitIdentifier(Identifier& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("Identifier", Color::Yellow);
|
|
os_ << " " << GetColor(Color::BrightCyan) << node.name << GetColor(Color::Reset);
|
|
if (options_.show_location)
|
|
{
|
|
os_ << " ";
|
|
PrintLocation(node.location);
|
|
}
|
|
os_ << "\n";
|
|
}
|
|
|
|
void DebugPrinter::VisitLiteral(Literal& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("Literal", Color::Yellow);
|
|
os_ << " [";
|
|
PrintLiteralKind(node.literal_kind);
|
|
os_ << "] " << GetColor(Color::BrightGreen) << node.name << GetColor(Color::Reset);
|
|
if (options_.show_location)
|
|
{
|
|
os_ << " ";
|
|
PrintLocation(node.location);
|
|
}
|
|
os_ << "\n";
|
|
}
|
|
|
|
void DebugPrinter::VisitBinaryExpression(BinaryExpression& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("BinaryExpression", Color::Yellow);
|
|
os_ << " ";
|
|
PrintOperator(node.op);
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
PrintExpression(node.left.get(), "left", false);
|
|
PrintExpression(node.right.get(), "right", true);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitComparisonExpression(ComparisonExpression& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("ComparisonExpression", Color::Yellow);
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
PrintExpression(node.left.get(), "left", false);
|
|
|
|
for (size_t i = 0; i < node.comparisons.size(); ++i)
|
|
{
|
|
bool is_last = (i == node.comparisons.size() - 1);
|
|
const auto& comp = node.comparisons[i];
|
|
|
|
PrintIndent(is_last);
|
|
PrintColored("comparison", Color::Green);
|
|
os_ << " ";
|
|
PrintOperator(comp.op);
|
|
os_ << ":\n";
|
|
|
|
is_last_child_stack_.push_back(is_last);
|
|
IncreaseIndent();
|
|
PrintExpression(comp.right.get(), "", true);
|
|
DecreaseIndent();
|
|
is_last_child_stack_.pop_back();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitUnaryExpression(UnaryExpression& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("UnaryExpression", Color::Yellow);
|
|
os_ << " ";
|
|
PrintOperator(node.op);
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
PrintExpression(node.argument.get(), "argument", true);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitTernaryExpression(TernaryExpression& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("TernaryExpression", Color::Yellow);
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
PrintExpression(node.condition.get(), "condition", false);
|
|
PrintExpression(node.consequence.get(), "consequence", false);
|
|
PrintExpression(node.alternative.get(), "alternative", true);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitCallExpression(CallExpression& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("CallExpression", Color::Yellow);
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
PrintExpression(node.callee.get(), "callee", false);
|
|
|
|
if (!node.arguments.empty())
|
|
{
|
|
PrintIndent(true);
|
|
PrintColored("arguments", Color::Green);
|
|
os_ << ":\n";
|
|
|
|
is_last_child_stack_.push_back(true);
|
|
IncreaseIndent();
|
|
|
|
for (size_t i = 0; i < node.arguments.size(); ++i)
|
|
{
|
|
bool is_last = (i == node.arguments.size() - 1);
|
|
const auto& arg = node.arguments[i];
|
|
|
|
PrintIndent(is_last);
|
|
if (arg.name)
|
|
{
|
|
PrintColored(*arg.name, Color::BrightCyan);
|
|
os_ << " = ";
|
|
}
|
|
os_ << "\n";
|
|
|
|
is_last_child_stack_.push_back(is_last);
|
|
IncreaseIndent();
|
|
PrintExpression(arg.value.get(), "", true);
|
|
DecreaseIndent();
|
|
is_last_child_stack_.pop_back();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
is_last_child_stack_.pop_back();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitAttributeExpression(AttributeExpression& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("AttributeExpression", Color::Yellow);
|
|
os_ << " ." << GetColor(Color::BrightCyan) << node.name << GetColor(Color::Reset);
|
|
if (options_.show_location)
|
|
{
|
|
os_ << " ";
|
|
PrintLocation(node.location);
|
|
}
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
PrintExpression(node.object.get(), "object", true);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitSubscriptExpression(SubscriptExpression& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("SubscriptExpression", Color::Yellow);
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
PrintExpression(node.value.get(), "value", false);
|
|
|
|
if (!node.indices.empty())
|
|
{
|
|
PrintIndent(true);
|
|
PrintColored("indices", Color::Green);
|
|
os_ << ":\n";
|
|
|
|
is_last_child_stack_.push_back(true);
|
|
IncreaseIndent();
|
|
|
|
for (size_t i = 0; i < node.indices.size(); ++i)
|
|
{
|
|
bool is_last = (i == node.indices.size() - 1);
|
|
const auto& idx = node.indices[i];
|
|
|
|
PrintIndent(is_last);
|
|
if (idx.is_slice)
|
|
{
|
|
PrintColored("slice", Color::Magenta);
|
|
}
|
|
else
|
|
{
|
|
PrintColored("index", Color::Magenta);
|
|
}
|
|
os_ << ":\n";
|
|
|
|
is_last_child_stack_.push_back(is_last);
|
|
IncreaseIndent();
|
|
|
|
if (idx.start)
|
|
{
|
|
PrintExpression(idx.start.get(), "start", !idx.end && !idx.step);
|
|
}
|
|
|
|
if (idx.end)
|
|
{
|
|
PrintExpression(idx.end.get(), "end", !idx.step);
|
|
}
|
|
|
|
if (idx.step)
|
|
{
|
|
PrintExpression(idx.step.get(), "step", true);
|
|
}
|
|
|
|
DecreaseIndent();
|
|
is_last_child_stack_.pop_back();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
is_last_child_stack_.pop_back();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitArrayExpression(ArrayExpression& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("ArrayExpression", Color::Yellow);
|
|
os_ << "\n";
|
|
|
|
if (node.elements.empty())
|
|
{
|
|
IncreaseIndent();
|
|
PrintIndent();
|
|
PrintColored("(empty)", Color::Gray);
|
|
os_ << "\n";
|
|
DecreaseIndent();
|
|
return;
|
|
}
|
|
|
|
IncreaseIndent();
|
|
|
|
for (size_t i = 0; i < node.elements.size(); ++i)
|
|
{
|
|
bool is_last = (i == node.elements.size() - 1);
|
|
const auto& elem = node.elements[i];
|
|
|
|
PrintIndent(is_last);
|
|
PrintColored("element", Color::Green);
|
|
if (elem.is_nested)
|
|
{
|
|
os_ << " " << GetColor(Color::Magenta) << "[nested]" << GetColor(Color::Reset);
|
|
}
|
|
os_ << ":\n";
|
|
|
|
is_last_child_stack_.push_back(is_last);
|
|
IncreaseIndent();
|
|
|
|
if (elem.key)
|
|
{
|
|
PrintExpression(elem.key.get(), "key", false);
|
|
PrintExpression(elem.value.get(), "value", true);
|
|
}
|
|
else
|
|
{
|
|
PrintExpression(elem.value.get(), "", true);
|
|
}
|
|
|
|
DecreaseIndent();
|
|
is_last_child_stack_.pop_back();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitAnonymousFunctionExpression(AnonymousFunctionExpression& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("AnonymousFunctionExpression", Color::Yellow);
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
PrintSignature(node.signature);
|
|
if (node.body)
|
|
{
|
|
PrintStatement(node.body.get(), "body", true);
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitPrefixIncrementExpression(PrefixIncrementExpression& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("PrefixIncrementExpression", Color::Yellow);
|
|
os_ << " ++\n";
|
|
|
|
IncreaseIndent();
|
|
PrintExpression(node.argument.get(), "argument", true);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitPrefixDecrementExpression(PrefixDecrementExpression& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("PrefixDecrementExpression", Color::Yellow);
|
|
os_ << " --\n";
|
|
|
|
IncreaseIndent();
|
|
PrintExpression(node.argument.get(), "argument", true);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitPostfixIncrementExpression(PostfixIncrementExpression& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("PostfixIncrementExpression", Color::Yellow);
|
|
os_ << " ++\n";
|
|
|
|
IncreaseIndent();
|
|
PrintExpression(node.argument.get(), "argument", true);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitPostfixDecrementExpression(PostfixDecrementExpression& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("PostfixDecrementExpression", Color::Yellow);
|
|
os_ << " --\n";
|
|
|
|
IncreaseIndent();
|
|
PrintExpression(node.argument.get(), "argument", true);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitFunctionPointerExpression(FunctionPointerExpression& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("FunctionPointerExpression", Color::Yellow);
|
|
os_ << " @\n";
|
|
|
|
IncreaseIndent();
|
|
PrintExpression(node.argument.get(), "argument", true);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitAssignmentExpression(AssignmentExpression& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("AssignmentExpression", Color::Yellow);
|
|
os_ << " ";
|
|
PrintOperator(node.op);
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
PrintLeftHandSide(node.left, "left", false);
|
|
PrintExpression(node.right.get(), "right", true);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitExpressionStatement(ExpressionStatement& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("ExpressionStatement", Color::BrightYellow);
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
PrintExpression(node.expression.get(), "", true);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitVarStatement(VarStatement& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("VarStatement", Color::BrightYellow);
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
for (size_t i = 0; i < node.declarations.size(); ++i)
|
|
{
|
|
bool is_last = (i == node.declarations.size() - 1);
|
|
is_last_child_stack_.push_back(is_last);
|
|
node.declarations[i]->Accept(*this);
|
|
is_last_child_stack_.pop_back();
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitStaticStatement(StaticStatement& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("StaticStatement", Color::BrightYellow);
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
for (size_t i = 0; i < node.declarations.size(); ++i)
|
|
{
|
|
bool is_last = (i == node.declarations.size() - 1);
|
|
is_last_child_stack_.push_back(is_last);
|
|
node.declarations[i]->Accept(*this);
|
|
is_last_child_stack_.pop_back();
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitGlobalStatement(GlobalStatement& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("GlobalStatement", Color::BrightYellow);
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
for (size_t i = 0; i < node.declarations.size(); ++i)
|
|
{
|
|
bool is_last = (i == node.declarations.size() - 1);
|
|
is_last_child_stack_.push_back(is_last);
|
|
node.declarations[i]->Accept(*this);
|
|
is_last_child_stack_.pop_back();
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitConstStatement(ConstStatement& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("ConstStatement", Color::BrightYellow);
|
|
os_ << " " << GetColor(Color::BrightCyan) << node.name << GetColor(Color::Reset);
|
|
if (node.type_name)
|
|
{
|
|
os_ << ": " << GetColor(Color::BrightBlue) << *node.type_name << GetColor(Color::Reset);
|
|
}
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
PrintExpression(node.value.get(), "value", true);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitAssignmentStatement(AssignmentStatement& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("AssignmentStatement", Color::BrightYellow);
|
|
os_ << " ";
|
|
PrintOperator(node.op);
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
PrintLeftHandSide(node.left, "left", false);
|
|
PrintExpression(node.right.get(), "right", true);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitBlockStatement(BlockStatement& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("BlockStatement", Color::BrightYellow);
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
PrintStatements(node.statements);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitIfStatement(IfStatement& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("IfStatement", Color::BrightYellow);
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
|
|
for (size_t i = 0; i < node.branches.size(); ++i)
|
|
{
|
|
bool is_last = (i == node.branches.size() - 1);
|
|
const auto& branch = node.branches[i];
|
|
|
|
PrintIndent(is_last);
|
|
PrintColored(i == 0 ? "if" : "elif", Color::Green);
|
|
os_ << ":\n";
|
|
|
|
is_last_child_stack_.push_back(is_last);
|
|
IncreaseIndent();
|
|
|
|
PrintExpression(branch.condition.get(), "condition", false);
|
|
PrintStatement(branch.body.get(), "body", true);
|
|
|
|
DecreaseIndent();
|
|
is_last_child_stack_.pop_back();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitForInStatement(ForInStatement& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("ForInStatement", Color::BrightYellow);
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
PrintColored("iterator", Color::Green);
|
|
os_ << ": ";
|
|
if (!node.key.empty())
|
|
{
|
|
PrintColored(node.key, Color::BrightCyan);
|
|
os_ << ", ";
|
|
}
|
|
PrintColored(node.value, Color::BrightCyan);
|
|
os_ << "\n";
|
|
|
|
PrintExpression(node.collection.get(), "collection", false);
|
|
PrintStatement(node.body.get(), "body", true);
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitForToStatement(ForToStatement& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("ForToStatement", Color::BrightYellow);
|
|
os_ << " " << GetColor(Color::BrightCyan) << node.counter << GetColor(Color::Reset);
|
|
if (node.is_downto)
|
|
{
|
|
os_ << " " << GetColor(Color::Magenta) << "[downto]" << GetColor(Color::Reset);
|
|
}
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
PrintExpression(node.start.get(), "start", false);
|
|
PrintExpression(node.end.get(), "end", false);
|
|
PrintStatement(node.body.get(), "body", true);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitWhileStatement(WhileStatement& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("WhileStatement", Color::BrightYellow);
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
PrintExpression(node.condition.get(), "condition", false);
|
|
PrintStatement(node.body.get(), "body", true);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitRepeatStatement(RepeatStatement& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("RepeatStatement", Color::BrightYellow);
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
|
|
if (!node.body.empty())
|
|
{
|
|
PrintIndent();
|
|
PrintColored("body", Color::Green);
|
|
os_ << ":\n";
|
|
|
|
IncreaseIndent();
|
|
PrintStatements(node.body);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
PrintExpression(node.condition.get(), "condition", true);
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitCaseStatement(CaseStatement& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("CaseStatement", Color::BrightYellow);
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
|
|
PrintExpression(node.discriminant.get(), "discriminant", false);
|
|
|
|
if (!node.branches.empty())
|
|
{
|
|
PrintIndent(!node.default_case);
|
|
PrintColored("branches", Color::Green);
|
|
os_ << ":\n";
|
|
|
|
is_last_child_stack_.push_back(!node.default_case);
|
|
IncreaseIndent();
|
|
|
|
for (size_t i = 0; i < node.branches.size(); ++i)
|
|
{
|
|
bool is_last = (i == node.branches.size() - 1);
|
|
const auto& branch = node.branches[i];
|
|
|
|
PrintIndent(is_last);
|
|
PrintColored("case", Color::Magenta);
|
|
os_ << ":\n";
|
|
|
|
is_last_child_stack_.push_back(is_last);
|
|
IncreaseIndent();
|
|
|
|
if (!branch.values.empty())
|
|
{
|
|
PrintIndent(false);
|
|
PrintColored("values", Color::Green);
|
|
os_ << ":\n";
|
|
|
|
IncreaseIndent();
|
|
for (size_t j = 0; j < branch.values.size(); ++j)
|
|
{
|
|
bool val_is_last = (j == branch.values.size() - 1);
|
|
is_last_child_stack_.push_back(val_is_last);
|
|
PrintExpression(branch.values[j].get(), "", val_is_last);
|
|
is_last_child_stack_.pop_back();
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
|
|
PrintStatement(branch.body.get(), "body", true);
|
|
|
|
DecreaseIndent();
|
|
is_last_child_stack_.pop_back();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
is_last_child_stack_.pop_back();
|
|
}
|
|
|
|
if (node.default_case)
|
|
{
|
|
PrintStatement(node.default_case.get(), "default", true);
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitTryStatement(TryStatement& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("TryStatement", Color::BrightYellow);
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
PrintStatement(node.try_body.get(), "try", false);
|
|
PrintStatement(node.except_body.get(), "except", true);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitBreakStatement(BreakStatement&)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("BreakStatement", Color::BrightYellow);
|
|
os_ << "\n";
|
|
}
|
|
|
|
void DebugPrinter::VisitContinueStatement(ContinueStatement&)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("ContinueStatement", Color::BrightYellow);
|
|
os_ << "\n";
|
|
}
|
|
|
|
void DebugPrinter::VisitReturnStatement(ReturnStatement& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("ReturnStatement", Color::BrightYellow);
|
|
os_ << "\n";
|
|
|
|
if (node.value)
|
|
{
|
|
IncreaseIndent();
|
|
PrintExpression(node.value.get(), "value", true);
|
|
DecreaseIndent();
|
|
}
|
|
}
|
|
|
|
void DebugPrinter::VisitUsesStatement(UsesStatement& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("UsesStatement", Color::BrightYellow);
|
|
os_ << ": ";
|
|
for (size_t i = 0; i < node.units.size(); ++i)
|
|
{
|
|
if (i > 0) os_ << ", ";
|
|
PrintColored(node.units[i], Color::BrightCyan);
|
|
}
|
|
os_ << "\n";
|
|
}
|
|
|
|
void DebugPrinter::VisitFunctionDefinition(FunctionDefinition& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("FunctionDefinition", Color::BrightYellow);
|
|
os_ << " " << GetColor(Color::BrightCyan) << node.name << GetColor(Color::Reset);
|
|
if (node.is_overload)
|
|
{
|
|
os_ << " " << GetColor(Color::Magenta) << "[overload]" << GetColor(Color::Reset);
|
|
}
|
|
if (options_.show_location)
|
|
{
|
|
os_ << " ";
|
|
PrintLocation(node.location);
|
|
}
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
PrintSignature(node.signature);
|
|
if (node.body)
|
|
{
|
|
PrintStatement(node.body.get(), "body", true);
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitFunctionDeclaration(FunctionDeclaration& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("FunctionDeclaration", Color::BrightYellow);
|
|
os_ << " " << GetColor(Color::BrightCyan) << node.name << GetColor(Color::Reset);
|
|
if (node.is_overload)
|
|
{
|
|
os_ << " " << GetColor(Color::Magenta) << "[overload]" << GetColor(Color::Reset);
|
|
}
|
|
if (options_.show_location)
|
|
{
|
|
os_ << " ";
|
|
PrintLocation(node.location);
|
|
}
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
PrintSignature(node.signature);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitVarDeclaration(VarDeclaration& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("VarDeclaration", Color::Yellow);
|
|
os_ << " " << GetColor(Color::BrightCyan) << node.name << GetColor(Color::Reset);
|
|
if (node.type)
|
|
{
|
|
os_ << ": " << GetColor(Color::BrightBlue) << node.type->name << GetColor(Color::Reset);
|
|
}
|
|
if (options_.show_location)
|
|
{
|
|
os_ << " ";
|
|
PrintLocation(node.location);
|
|
}
|
|
os_ << "\n";
|
|
|
|
if (node.initial_value)
|
|
{
|
|
IncreaseIndent();
|
|
PrintExpression(node.initial_value.get(), "initial_value", true);
|
|
DecreaseIndent();
|
|
}
|
|
}
|
|
|
|
void DebugPrinter::VisitStaticDeclaration(StaticDeclaration& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("StaticDeclaration", Color::Yellow);
|
|
os_ << " " << GetColor(Color::BrightCyan) << node.name << GetColor(Color::Reset);
|
|
PrintReferenceModifier(node.reference_modifier);
|
|
if (node.type)
|
|
{
|
|
os_ << ": " << GetColor(Color::BrightBlue) << node.type->name << GetColor(Color::Reset);
|
|
}
|
|
if (options_.show_location)
|
|
{
|
|
os_ << " ";
|
|
PrintLocation(node.location);
|
|
}
|
|
os_ << "\n";
|
|
|
|
if (node.initial_value)
|
|
{
|
|
IncreaseIndent();
|
|
PrintExpression(node.initial_value.get(), "initial_value", true);
|
|
DecreaseIndent();
|
|
}
|
|
}
|
|
|
|
void DebugPrinter::VisitGlobalDeclaration(GlobalDeclaration& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("GlobalDeclaration", Color::Yellow);
|
|
os_ << " " << GetColor(Color::BrightCyan) << node.name << GetColor(Color::Reset);
|
|
if (node.type)
|
|
{
|
|
os_ << ": " << GetColor(Color::BrightBlue) << node.type->name << GetColor(Color::Reset);
|
|
}
|
|
if (options_.show_location)
|
|
{
|
|
os_ << " ";
|
|
PrintLocation(node.location);
|
|
}
|
|
os_ << "\n";
|
|
|
|
if (node.initial_value)
|
|
{
|
|
IncreaseIndent();
|
|
PrintExpression(node.initial_value.get(), "initial_value", true);
|
|
DecreaseIndent();
|
|
}
|
|
}
|
|
|
|
void DebugPrinter::VisitFieldDeclaration(FieldDeclaration& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("FieldDeclaration", Color::Yellow);
|
|
os_ << " " << GetColor(Color::BrightCyan) << node.name << GetColor(Color::Reset);
|
|
PrintReferenceModifier(node.reference_modifier);
|
|
if (node.type)
|
|
{
|
|
os_ << ": " << GetColor(Color::BrightBlue) << node.type->name << GetColor(Color::Reset);
|
|
}
|
|
os_ << "\n";
|
|
|
|
if (node.initial_value)
|
|
{
|
|
IncreaseIndent();
|
|
PrintExpression(node.initial_value.get(), "initial_value", true);
|
|
DecreaseIndent();
|
|
}
|
|
}
|
|
|
|
void DebugPrinter::VisitUnpackPattern(UnpackPattern& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("UnpackPattern", Color::Yellow);
|
|
os_ << " [";
|
|
for (size_t i = 0; i < node.names.size(); ++i)
|
|
{
|
|
if (i > 0) os_ << ", ";
|
|
PrintColored(node.names[i], Color::BrightCyan);
|
|
}
|
|
os_ << "]\n";
|
|
}
|
|
|
|
void DebugPrinter::VisitTSSQLExpression(TSSQLExpression& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("TSSQLExpression", Color::Yellow);
|
|
|
|
std::string type_str;
|
|
switch (node.sql_type)
|
|
{
|
|
case TSSQLExpressionType::kSelect: type_str = "SELECT"; break;
|
|
case TSSQLExpressionType::kSSelect: type_str = "SSELECT"; break;
|
|
case TSSQLExpressionType::kVSelect: type_str = "VSELECT"; break;
|
|
case TSSQLExpressionType::kMSelect: type_str = "MSELECT"; break;
|
|
case TSSQLExpressionType::kUpdate: type_str = "UPDATE"; break;
|
|
case TSSQLExpressionType::kDelete: type_str = "DELETE"; break;
|
|
case TSSQLExpressionType::kInsert: type_str = "INSERT"; break;
|
|
default: type_str = "UNKNOWN"; break;
|
|
}
|
|
|
|
os_ << " [" << GetColor(Color::BrightBlue) << type_str << GetColor(Color::Reset) << "]\n";
|
|
|
|
IncreaseIndent();
|
|
PrintIndent();
|
|
PrintColored("sql", Color::Green);
|
|
os_ << ": " << GetColor(Color::BrightGreen) << EscapeString(node.raw_sql) << GetColor(Color::Reset) << "\n";
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitMatrixIterationStatement(MatrixIterationStatement& node)
|
|
{
|
|
PrintIndent();
|
|
PrintColored("MatrixIterationStatement", Color::BrightYellow);
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
PrintExpression(node.target.get(), "target", false);
|
|
PrintStatement(node.body.get(), "body", true);
|
|
DecreaseIndent();
|
|
}
|
|
}
|