#include #include #include "./debug_printer.hpp" namespace lsp::language::ast { // ===== 辅助函数实现 ===== const char* DebugPrinter::GetColor(const char* color) const { return options_.use_colors ? color : ""; } void DebugPrinter::PrintColored(const std::string& text, const char* color) { os_ << GetColor(color) << text << GetColor(Color::Reset); } std::string DebugPrinter::GetIndent() const { return std::string(current_indent_, ' '); } void DebugPrinter::PrintIndent(bool is_last) { if (options_.use_tree_chars && current_indent_ > 0) { PrintTreePrefix(is_last); } else { os_ << GetIndent(); } } void DebugPrinter::PrintTreePrefix(bool is_last) { std::string prefix; for (size_t i = 0; i < is_last_child_stack_.size(); ++i) { if (is_last_child_stack_[i]) { prefix += " "; } else { prefix += "│ "; } } if (is_last) { prefix += "└── "; } else { prefix += "├── "; } os_ << GetColor(Color::Gray) << prefix << GetColor(Color::Reset); } std::string DebugPrinter::EscapeString(const std::string& str) const { std::string result; for (char c : str) { switch (c) { case '\n': result += "\\n"; break; case '\r': result += "\\r"; break; case '\t': result += "\\t"; break; case '\\': result += "\\\\"; break; case '"': result += "\\\""; break; default: if (c >= 32 && c < 127) result += c; else { char buf[5]; snprintf(buf, sizeof(buf), "\\x%02x", static_cast(c)); result += buf; } } } 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 - 3) + "..."; } std::string DebugPrinter::GetSourceText(const Location& loc) const { if (!source_code_ || source_code_->empty()) return ""; size_t start = loc.start_byte; size_t end = loc.end_byte; if (start >= source_code_->length() || end > source_code_->length() || start >= end) return ""; std::string text = source_code_->substr(start, end - start); // 移除首尾空白 size_t first = text.find_first_not_of(" \t\n\r"); if (first == std::string::npos) return ""; size_t last = text.find_last_not_of(" \t\n\r"); text = text.substr(first, last - first + 1); // 压缩多个空白为单个空格 bool prev_space = false; std::string result; for (char c : text) { if (std::isspace(c)) { if (!prev_space) result += ' '; prev_space = true; } else { result += c; prev_space = false; } } return TruncateString(result, options_.max_source_length); } void DebugPrinter::PrintLocation(const Location& loc) { if (!options_.show_location) return; os_ << GetColor(Color::Gray) << "@"; os_ << loc.start_line << ":" << loc.start_column; if (loc.end_line != loc.start_line || loc.end_column != loc.start_column) { os_ << "-" << loc.end_line << ":" << loc.end_column; } os_ << GetColor(Color::Reset); } void DebugPrinter::PrintSourceSnippet(const Location& loc) { if (!options_.show_source_code) return; std::string source = GetSourceText(loc); if (!source.empty()) { os_ << " " << GetColor(Color::Dim) << "«" << source << "»" << GetColor(Color::Reset); } } void DebugPrinter::PrintNodeHeader(const std::string& type_name, const Location& loc) { PrintIndent(); // 打印节点类型 PrintColored(type_name, Color::BrightCyan); // 打印位置 if (options_.show_location || options_.show_source_code) { os_ << " "; PrintLocation(loc); PrintSourceSnippet(loc); } os_ << "\n"; } void DebugPrinter::PrintKeyValue(const std::string& key, const std::string& value, const char* value_color) { if (options_.compact_mode && value.empty()) return; PrintIndent(); PrintColored(key + ": ", Color::Yellow); if (value_color) PrintColored(value, value_color); else os_ << value; os_ << "\n"; } void DebugPrinter::PrintKeyValue(const std::string& key, int value) { PrintIndent(); PrintColored(key + ": ", Color::Yellow); PrintColored(std::to_string(value), Color::BrightGreen); os_ << "\n"; } void DebugPrinter::PrintKeyValue(const std::string& key, bool value) { PrintIndent(); PrintColored(key + ": ", Color::Yellow); PrintColored(value ? "true" : "false", value ? Color::Green : Color::Red); os_ << "\n"; } // ===== 打印主函数 ===== void DebugPrinter::Print(const ASTNode* node) { if (!node) { os_ << GetColor(Color::Red) << "(null)" << GetColor(Color::Reset) << "\n"; return; } const_cast(node)->Accept(*this); } void DebugPrinter::PrintStatements(const std::vector& statements) { for (size_t i = 0; i < statements.size(); ++i) { if (statements[i]) { bool is_last = (i == statements.size() - 1); if (options_.use_tree_chars) { is_last_child_stack_.push_back(is_last); statements[i]->Accept(*this); is_last_child_stack_.pop_back(); } else { statements[i]->Accept(*this); } } } } void DebugPrinter::PrintParseResult(const ParseResult& result) { // 打印头部 PrintColored("╔═══════════════════════════════════════════════════════════════\n", Color::BrightBlue); PrintColored("║ ", Color::BrightBlue); PrintColored("AST Parse Result", Color::BrightCyan); os_ << "\n"; PrintColored("╠═══════════════════════════════════════════════════════════════\n", Color::BrightBlue); // 打印统计信息 if (result.root) { PrintColored("║ ", Color::BrightBlue); PrintColored("Statements: ", Color::Yellow); PrintColored(std::to_string(result.root->statements.size()), Color::BrightGreen); os_ << "\n"; } PrintColored("║ ", Color::BrightBlue); PrintColored("Errors: ", Color::Yellow); if (result.errors.empty()) { PrintColored("0", Color::Green); os_ << " "; PrintColored("✓", Color::BrightGreen); } else { PrintColored(std::to_string(result.errors.size()), Color::BrightRed); os_ << " "; PrintColored("✗", Color::BrightRed); } os_ << "\n"; PrintColored("╚═══════════════════════════════════════════════════════════════\n", Color::BrightBlue); // 打印错误 if (!result.errors.empty()) { os_ << "\n"; PrintColored("Errors:\n", Color::BrightRed); for (const auto& error : result.errors) { PrintError(error); } os_ << "\n"; } // 打印AST if (result.root) { os_ << "\n"; PrintColored("AST Tree:\n", Color::BrightCyan); Print(result.root.get()); } } void DebugPrinter::PrintError(const ParseError& error) { PrintIndent(); // 错误级别 const char* severity_color = Color::Red; std::string severity_text = "ERROR"; switch (error.severity) { case ErrorSeverity::Warning: severity_color = Color::Yellow; severity_text = "WARNING"; break; case ErrorSeverity::Fatal: severity_color = Color::BrightRed; severity_text = "FATAL"; break; default: break; } PrintColored(severity_text, severity_color); os_ << " "; // 位置 PrintLocation(error.location); os_ << " "; // 消息 os_ << error.message << "\n"; } void DebugPrinter::PrintExpression(const Expression* expr, const std::string& label, bool is_last) { if (!label.empty()) { PrintIndent(); PrintColored(label + ":\n", Color::Yellow); } IncreaseIndent(); if (expr) { if (options_.use_tree_chars) { is_last_child_stack_.push_back(is_last); const_cast(expr)->Accept(*this); is_last_child_stack_.pop_back(); } else { const_cast(expr)->Accept(*this); } } else { if (options_.use_tree_chars) { is_last_child_stack_.push_back(is_last); } PrintIndent(is_last); PrintColored("(null)", Color::Red); os_ << "\n"; if (options_.use_tree_chars) { is_last_child_stack_.pop_back(); } } DecreaseIndent(); } void DebugPrinter::PrintStatement(const Statement* stmt, const std::string& label, bool is_last) { if (!label.empty()) { PrintIndent(); PrintColored(label + ":\n", Color::Yellow); } IncreaseIndent(); if (stmt) { if (options_.use_tree_chars) { is_last_child_stack_.push_back(is_last); const_cast(stmt)->Accept(*this); is_last_child_stack_.pop_back(); } else { const_cast(stmt)->Accept(*this); } } else { if (options_.use_tree_chars) { is_last_child_stack_.push_back(is_last); } PrintIndent(is_last); PrintColored("(null)", Color::Red); os_ << "\n"; if (options_.use_tree_chars) { is_last_child_stack_.pop_back(); } } DecreaseIndent(); } void DebugPrinter::PrintSignature(const Signature& sig) { if (!sig.parameters.empty()) { PrintIndent(); PrintColored("parameters", Color::Yellow); PrintColored(" (" + std::to_string(sig.parameters.size()) + "):\n", Color::Gray); IncreaseIndent(); for (size_t i = 0; i < sig.parameters.size(); ++i) { bool is_last = (i == sig.parameters.size() - 1); if (options_.use_tree_chars) { is_last_child_stack_.push_back(is_last); PrintParameter(sig.parameters[i], is_last); is_last_child_stack_.pop_back(); } else { PrintParameter(sig.parameters[i], is_last); } } DecreaseIndent(); } if (sig.return_type) { PrintKeyValue("return_type", *sig.return_type, Color::BrightMagenta); } } void DebugPrinter::PrintParameter(const Parameter& param, bool is_last) { PrintIndent(is_last); PrintColored(param.name, Color::BrightGreen); if (param.is_var) os_ << " " << GetColor(Color::Cyan) << "[var]" << GetColor(Color::Reset); if (param.is_out) os_ << " " << GetColor(Color::Cyan) << "[out]" << GetColor(Color::Reset); if (param.type_name) os_ << GetColor(Color::Gray) << ": " << GetColor(Color::BrightMagenta) << *param.type_name << GetColor(Color::Reset); if (param.default_value) { os_ << " " << GetColor(Color::Gray) << "= " << GetColor(Color::Reset); os_ << "..."; // 简化显示 } os_ << "\n"; } void DebugPrinter::PrintLeftHandSide(const LeftHandSide& lhs, const std::string& label, bool is_last) { if (!label.empty()) { PrintIndent(); PrintColored(label + ":\n", Color::Yellow); IncreaseIndent(); } if (options_.use_tree_chars) { is_last_child_stack_.push_back(is_last); } std::visit([this](auto&& arg) { using T = std::decay_t; if constexpr (std::is_same_v> || std::is_same_v> || std::is_same_v> || std::is_same_v> || std::is_same_v> || std::is_same_v> || std::is_same_v> || std::is_same_v>) { if (arg) { arg->Accept(*this); } else { PrintIndent(); PrintColored("(null)", Color::Red); os_ << "\n"; } } }, lhs); if (options_.use_tree_chars) { is_last_child_stack_.pop_back(); } if (!label.empty()) { DecreaseIndent(); } } // ===== 枚举打印实现 ===== void DebugPrinter::PrintOperator(BinaryOperator op) { PrintColored(GetBinaryOperatorSymbol(op), Color::BrightYellow); } void DebugPrinter::PrintOperator(UnaryOperator op) { const char* 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 = ".!!"; break; case UnaryOperator::kMatrixTranspose: symbol = "`"; break; case UnaryOperator::kDerivative: symbol = "!"; break; case UnaryOperator::kExprAt: symbol = "@"; break; case UnaryOperator::kExprRef: symbol = "&"; break; } PrintColored(symbol, Color::BrightYellow); } void DebugPrinter::PrintOperator(AssignmentOperator op) { PrintColored(GetAssignmentOperatorSymbol(op), Color::BrightYellow); } void DebugPrinter::PrintLiteralKind(LiteralKind kind) { const char* kind_str = ""; const char* color = Color::Magenta; switch (kind) { case LiteralKind::kNumber: kind_str = "number"; break; case LiteralKind::kString: kind_str = "string"; color = Color::Green; break; case LiteralKind::kBoolean: kind_str = "boolean"; break; case LiteralKind::kNil: kind_str = "nil"; color = Color::Gray; break; case LiteralKind::kInfinity: kind_str = "infinity"; break; case LiteralKind::kEllipsis: kind_str = "ellipsis"; break; } PrintColored(kind_str, color); } void DebugPrinter::PrintAccessModifier(AccessModifier modifier) { const char* mod_str = ""; const char* color = Color::Cyan; switch (modifier) { case AccessModifier::kPublic: mod_str = "public"; break; case AccessModifier::kProtected: mod_str = "protected"; color = Color::Yellow; break; case AccessModifier::kPrivate: mod_str = "private"; color = Color::Red; break; } PrintColored(mod_str, color); } void DebugPrinter::PrintMethodModifier(MethodModifier modifier) { const char* mod_str = ""; switch (modifier) { case MethodModifier::kNone: mod_str = "none"; break; case MethodModifier::kVirtual: mod_str = "virtual"; break; case MethodModifier::kOverride: mod_str = "override"; break; case MethodModifier::kOverload: mod_str = "overload"; break; } PrintColored(mod_str, Color::Magenta); } void DebugPrinter::PrintReferenceModifier(ReferenceModifier modifier) { const char* mod_str = ""; switch (modifier) { case ReferenceModifier::kNone: mod_str = "none"; break; case ReferenceModifier::kWeakRef: mod_str = "weakref"; break; case ReferenceModifier::kAutoRef: mod_str = "autoref"; break; } PrintColored(mod_str, Color::Cyan); } // ===== Visitor 实现 ===== void DebugPrinter::VisitProgram(Program& node) { PrintNodeHeader("Program", node.location); if (!node.statements.empty()) { IncreaseIndent(); PrintIndent(); PrintColored("statements ", Color::Yellow); PrintColored("(" + std::to_string(node.statements.size()) + "):\n", Color::Gray); IncreaseIndent(); PrintStatements(node.statements); DecreaseIndent(); DecreaseIndent(); } } void DebugPrinter::VisitIdentifier(Identifier& node) { PrintNodeHeader("Identifier", node.location); IncreaseIndent(); PrintKeyValue("name", node.name, Color::BrightGreen); DecreaseIndent(); } void DebugPrinter::VisitLiteral(Literal& node) { PrintNodeHeader("Literal", node.location); IncreaseIndent(); PrintIndent(); PrintColored("kind: ", Color::Yellow); PrintLiteralKind(node.literal_kind); os_ << "\n"; PrintIndent(); PrintColored("value: ", Color::Yellow); if (node.literal_kind == LiteralKind::kString) { PrintColored("\"" + EscapeString(node.value) + "\"", Color::Green); } else { PrintColored(node.value, Color::BrightGreen); } os_ << "\n"; DecreaseIndent(); } void DebugPrinter::VisitBinaryExpression(BinaryExpression& node) { PrintNodeHeader("BinaryExpression", node.location); IncreaseIndent(); PrintIndent(); PrintColored("operator: ", Color::Yellow); PrintOperator(node.op); os_ << "\n"; PrintExpression(node.left.get(), "left", false); PrintExpression(node.right.get(), "right", true); DecreaseIndent(); } void DebugPrinter::VisitComparisonExpression(ComparisonExpression& node) { PrintNodeHeader("ComparisonExpression", node.location); IncreaseIndent(); PrintExpression(node.left.get(), "left", false); if (!node.comparisons.empty()) { PrintIndent(); PrintColored("comparisons ", Color::Yellow); PrintColored("(" + std::to_string(node.comparisons.size()) + "):\n", Color::Gray); IncreaseIndent(); for (size_t i = 0; i < node.comparisons.size(); ++i) { const auto& comp = node.comparisons[i]; PrintIndent(); PrintColored("[" + std::to_string(i) + "] ", Color::Gray); PrintOperator(comp.op); os_ << "\n"; if (comp.right) { IncreaseIndent(); PrintExpression(comp.right.get()); DecreaseIndent(); } } DecreaseIndent(); } DecreaseIndent(); } void DebugPrinter::VisitUnaryExpression(UnaryExpression& node) { PrintNodeHeader("UnaryExpression", node.location); IncreaseIndent(); PrintIndent(); PrintColored("operator: ", Color::Yellow); PrintOperator(node.op); os_ << "\n"; PrintExpression(node.argument.get(), "argument", true); DecreaseIndent(); } void DebugPrinter::VisitTernaryExpression(TernaryExpression& node) { PrintNodeHeader("TernaryExpression", node.location); 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) { PrintNodeHeader("CallExpression", node.location); IncreaseIndent(); bool has_arguments = !node.arguments.empty(); PrintExpression(node.callee.get(), "callee", !has_arguments); if (has_arguments) { PrintIndent(); PrintColored("arguments ", Color::Yellow); PrintColored("(" + std::to_string(node.arguments.size()) + "):\n", Color::Gray); IncreaseIndent(); for (size_t i = 0; i < node.arguments.size(); ++i) { const auto& arg = node.arguments[i]; bool is_last = (i == node.arguments.size() - 1); if (options_.use_tree_chars) { is_last_child_stack_.push_back(is_last); } PrintIndent(is_last); PrintColored("[" + std::to_string(i) + "]", Color::Gray); if (arg.name) { os_ << " " << GetColor(Color::Yellow) << *arg.name << GetColor(Color::Reset) << ":"; } if (arg.is_spread) { os_ << " " << GetColor(Color::Magenta) << "..." << GetColor(Color::Reset); } os_ << "\n"; if (arg.value) { IncreaseIndent(); arg.value->Accept(*this); DecreaseIndent(); } if (options_.use_tree_chars) { is_last_child_stack_.pop_back(); } } DecreaseIndent(); } DecreaseIndent(); } void DebugPrinter::VisitAttributeExpression(AttributeExpression& node) { PrintNodeHeader("AttributeExpression", node.location); IncreaseIndent(); PrintExpression(node.object.get(), "object", false); PrintKeyValue("attribute", node.attribute, Color::BrightGreen); DecreaseIndent(); } void DebugPrinter::VisitSubscriptExpression(SubscriptExpression& node) { PrintNodeHeader("SubscriptExpression", node.location); IncreaseIndent(); PrintExpression(node.value.get(), "value"); if (!node.indices.empty()) { PrintIndent(); PrintColored("indices ", Color::Yellow); PrintColored("(" + std::to_string(node.indices.size()) + "):\n", Color::Gray); IncreaseIndent(); for (size_t i = 0; i < node.indices.size(); ++i) { const auto& idx = node.indices[i]; PrintIndent(); PrintColored("[" + std::to_string(i) + "]", Color::Gray); if (idx.is_slice) { os_ << " " << GetColor(Color::Cyan) << "[slice]" << GetColor(Color::Reset); } if (idx.is_empty_slice) { os_ << " " << GetColor(Color::Cyan) << "[empty]" << GetColor(Color::Reset); } os_ << "\n"; IncreaseIndent(); if (idx.start) { PrintExpression(idx.start.get(), "start"); } if (idx.end) { PrintExpression(idx.end.get(), "end"); } if (idx.step) { PrintExpression(idx.step.get(), "step"); } DecreaseIndent(); } DecreaseIndent(); } DecreaseIndent(); } void DebugPrinter::VisitArrayExpression(ArrayExpression& node) { PrintNodeHeader("ArrayExpression", node.location); IncreaseIndent(); if (!node.elements.empty()) { PrintIndent(); PrintColored("elements ", Color::Yellow); PrintColored("(" + std::to_string(node.elements.size()) + "):\n", Color::Gray); IncreaseIndent(); for (size_t i = 0; i < node.elements.size(); ++i) { const auto& elem = node.elements[i]; PrintIndent(); PrintColored("[" + std::to_string(i) + "]", Color::Gray); if (elem.is_nested) { os_ << " " << GetColor(Color::Cyan) << "[nested]" << GetColor(Color::Reset); } os_ << "\n"; IncreaseIndent(); if (elem.key) { PrintExpression(elem.key.get(), "key"); } if (elem.value) { PrintExpression(elem.value.get(), "value"); } DecreaseIndent(); } DecreaseIndent(); } DecreaseIndent(); } void DebugPrinter::VisitAnonymousFunctionExpression(AnonymousFunctionExpression& node) { PrintNodeHeader("AnonymousFunction", node.location); IncreaseIndent(); PrintSignature(node.signature); if (node.body) { PrintStatement(node.body.get(), "body", true); PrintStatement(node.body.get(), "body", true); } DecreaseIndent(); } void DebugPrinter::VisitPrefixIncrementExpression(PrefixIncrementExpression& node) { PrintNodeHeader("PrefixIncrement", node.location); IncreaseIndent(); PrintExpression(node.argument.get(), "argument", true); DecreaseIndent(); } void DebugPrinter::VisitPrefixDecrementExpression(PrefixDecrementExpression& node) { PrintNodeHeader("PrefixDecrement", node.location); IncreaseIndent(); PrintExpression(node.argument.get(), "argument", true); DecreaseIndent(); } void DebugPrinter::VisitPostfixIncrementExpression(PostfixIncrementExpression& node) { PrintNodeHeader("PostfixIncrement", node.location); IncreaseIndent(); PrintExpression(node.argument.get(), "argument", true); DecreaseIndent(); } void DebugPrinter::VisitPostfixDecrementExpression(PostfixDecrementExpression& node) { PrintNodeHeader("PostfixDecrement", node.location); IncreaseIndent(); PrintExpression(node.argument.get(), "argument", true); DecreaseIndent(); } void DebugPrinter::VisitFunctionPointerExpression(FunctionPointerExpression& node) { PrintNodeHeader("FunctionPointer", node.location); IncreaseIndent(); PrintExpression(node.argument.get(), "argument", true); DecreaseIndent(); } void DebugPrinter::VisitAssignmentExpression(AssignmentExpression& node) { PrintNodeHeader("AssignmentExpression", node.location); IncreaseIndent(); PrintIndent(); PrintColored("operator: ", Color::Yellow); PrintOperator(node.op); os_ << "\n"; PrintLeftHandSide(node.left, "left", false); PrintExpression(node.right.get(), "right", true); DecreaseIndent(); } void DebugPrinter::VisitExpressionStatement(ExpressionStatement& node) { PrintNodeHeader("ExpressionStatement", node.location); IncreaseIndent(); PrintExpression(node.expression.get(), "", true); DecreaseIndent(); } void DebugPrinter::VisitVarStatement(VarStatement& node) { PrintNodeHeader("VarStatement", node.location); IncreaseIndent(); if (!node.declarations.empty()) { PrintIndent(); PrintColored("declarations ", Color::Yellow); PrintColored("(" + std::to_string(node.declarations.size()) + "):\n", Color::Gray); IncreaseIndent(); for (size_t i = 0; i < node.declarations.size(); ++i) { bool is_last = (i == node.declarations.size() - 1); if (node.declarations[i]) { if (options_.use_tree_chars) { is_last_child_stack_.push_back(is_last); node.declarations[i]->Accept(*this); is_last_child_stack_.pop_back(); } else { node.declarations[i]->Accept(*this); } } } DecreaseIndent(); } DecreaseIndent(); } void DebugPrinter::VisitStaticStatement(StaticStatement& node) { PrintNodeHeader("StaticStatement", node.location); IncreaseIndent(); if (!node.declarations.empty()) { PrintIndent(); PrintColored("declarations ", Color::Yellow); PrintColored("(" + std::to_string(node.declarations.size()) + "):\n", Color::Gray); IncreaseIndent(); for (size_t i = 0; i < node.declarations.size(); ++i) { bool is_last = (i == node.declarations.size() - 1); if (node.declarations[i]) { if (options_.use_tree_chars) { is_last_child_stack_.push_back(is_last); node.declarations[i]->Accept(*this); is_last_child_stack_.pop_back(); } else { node.declarations[i]->Accept(*this); } } } DecreaseIndent(); } DecreaseIndent(); } void DebugPrinter::VisitGlobalStatement(GlobalStatement& node) { PrintNodeHeader("GlobalStatement", node.location); IncreaseIndent(); if (!node.declarations.empty()) { PrintIndent(); PrintColored("declarations ", Color::Yellow); PrintColored("(" + std::to_string(node.declarations.size()) + "):\n", Color::Gray); IncreaseIndent(); for (size_t i = 0; i < node.declarations.size(); ++i) { bool is_last = (i == node.declarations.size() - 1); if (node.declarations[i]) { if (options_.use_tree_chars) { is_last_child_stack_.push_back(is_last); node.declarations[i]->Accept(*this); is_last_child_stack_.pop_back(); } else { node.declarations[i]->Accept(*this); } } } DecreaseIndent(); } DecreaseIndent(); } void DebugPrinter::VisitConstStatement(ConstStatement& node) { PrintNodeHeader("ConstStatement", node.location); IncreaseIndent(); PrintKeyValue("name", node.name, Color::BrightGreen); if (node.type_name) { PrintKeyValue("type", *node.type_name, Color::BrightMagenta); } if (node.value) { PrintExpression(node.value.get(), "value", true); } DecreaseIndent(); } void DebugPrinter::VisitAssignmentStatement(AssignmentStatement& node) { PrintNodeHeader("AssignmentStatement", node.location); IncreaseIndent(); PrintIndent(); PrintColored("operator: ", Color::Yellow); PrintOperator(node.op); os_ << "\n"; PrintLeftHandSide(node.left, "left", false); PrintExpression(node.right.get(), "right", true); DecreaseIndent(); } void DebugPrinter::VisitBlockStatement(BlockStatement& node) { PrintNodeHeader("BlockStatement", node.location); if (!node.statements.empty()) { IncreaseIndent(); PrintStatements(node.statements); DecreaseIndent(); } } void DebugPrinter::VisitIfStatement(IfStatement& node) { PrintNodeHeader("IfStatement", node.location); IncreaseIndent(); if (!node.branches.empty()) { PrintIndent(); PrintColored("branches ", Color::Yellow); PrintColored("(" + std::to_string(node.branches.size()) + "):\n", Color::Gray); IncreaseIndent(); for (size_t i = 0; i < node.branches.size(); ++i) { const auto& branch = node.branches[i]; PrintIndent(); PrintColored("[" + std::to_string(i) + "]", Color::Gray); os_ << "\n"; IncreaseIndent(); if (branch.condition) { PrintExpression(branch.condition.get(), "condition"); } if (branch.body) { PrintStatement(branch.body.get(), "body"); } DecreaseIndent(); } DecreaseIndent(); } DecreaseIndent(); } void DebugPrinter::VisitForInStatement(ForInStatement& node) { PrintNodeHeader("ForInStatement", node.location); IncreaseIndent(); if (!node.key.empty()) { PrintKeyValue("key", node.key, Color::BrightGreen); } if (!node.value.empty()) { PrintKeyValue("value", node.value, Color::BrightGreen); } PrintExpression(node.collection.get(), "collection", false); if (node.body) { PrintStatement(node.body.get(), "body", true); } DecreaseIndent(); } void DebugPrinter::VisitForToStatement(ForToStatement& node) { PrintNodeHeader("ForToStatement", node.location); IncreaseIndent(); PrintKeyValue("counter", node.counter, Color::BrightGreen); if (node.is_downto) { PrintKeyValue("direction", "downto", Color::Cyan); } PrintExpression(node.start.get(), "start", false); PrintExpression(node.end.get(), "end", false); if (node.body) { PrintStatement(node.body.get(), "body", true); } DecreaseIndent(); } void DebugPrinter::VisitWhileStatement(WhileStatement& node) { PrintNodeHeader("WhileStatement", node.location); IncreaseIndent(); PrintExpression(node.condition.get(), "condition", false); if (node.body) { PrintStatement(node.body.get(), "body", true); } DecreaseIndent(); } void DebugPrinter::VisitRepeatStatement(RepeatStatement& node) { PrintNodeHeader("RepeatStatement", node.location); IncreaseIndent(); if (!node.body.empty()) { PrintIndent(); PrintColored("body ", Color::Yellow); PrintColored("(" + std::to_string(node.body.size()) + "):\n", Color::Gray); IncreaseIndent(); PrintStatements(node.body); DecreaseIndent(); } PrintExpression(node.condition.get(), "condition", true); DecreaseIndent(); } void DebugPrinter::VisitCaseStatement(CaseStatement& node) { PrintNodeHeader("CaseStatement", node.location); IncreaseIndent(); PrintExpression(node.discriminant.get(), "discriminant"); if (!node.branches.empty()) { PrintIndent(); PrintColored("branches ", Color::Yellow); PrintColored("(" + std::to_string(node.branches.size()) + "):\n", Color::Gray); IncreaseIndent(); for (size_t i = 0; i < node.branches.size(); ++i) { const auto& branch = node.branches[i]; PrintIndent(); PrintColored("[" + std::to_string(i) + "]", Color::Gray); os_ << "\n"; IncreaseIndent(); if (!branch.values.empty()) { PrintIndent(); PrintColored("values ", Color::Yellow); PrintColored("(" + std::to_string(branch.values.size()) + "):\n", Color::Gray); IncreaseIndent(); for (const auto& val : branch.values) { if (val) val->Accept(*this); } DecreaseIndent(); } if (branch.body) { PrintStatement(branch.body.get(), "body"); } DecreaseIndent(); } DecreaseIndent(); } if (node.default_case) { PrintStatement(node.default_case.get(), "default_case"); } DecreaseIndent(); } void DebugPrinter::VisitTryStatement(TryStatement& node) { PrintNodeHeader("TryStatement", node.location); IncreaseIndent(); if (node.try_body) { PrintStatement(node.try_body.get(), "try_body"); } if (node.except_body) { PrintStatement(node.except_body.get(), "except_body"); } DecreaseIndent(); } void DebugPrinter::VisitBreakStatement(BreakStatement& node) { PrintNodeHeader("BreakStatement", node.location); } void DebugPrinter::VisitContinueStatement(ContinueStatement& node) { PrintNodeHeader("ContinueStatement", node.location); } void DebugPrinter::VisitReturnStatement(ReturnStatement& node) { PrintNodeHeader("ReturnStatement", node.location); if (node.value) { IncreaseIndent(); PrintExpression(node.value.get(), "value", true); DecreaseIndent(); } } void DebugPrinter::VisitUsesStatement(UsesStatement& node) { PrintNodeHeader("UsesStatement", node.location); IncreaseIndent(); if (!node.units.empty()) { PrintIndent(); PrintColored("units: ", Color::Yellow); os_ << "["; for (size_t i = 0; i < node.units.size(); ++i) { if (i > 0) os_ << ", "; PrintColored(node.units[i], Color::BrightGreen); } os_ << "]\n"; } DecreaseIndent(); } void DebugPrinter::VisitFunctionDefinition(FunctionDefinition& node) { PrintNodeHeader("FunctionDefinition", node.location); IncreaseIndent(); PrintKeyValue("name", node.name, Color::BrightCyan); if (node.is_overload) { PrintKeyValue("overload", true); } PrintSignature(node.signature); if (node.body) { PrintStatement(node.body.get(), "body", true); } DecreaseIndent(); } void DebugPrinter::VisitFunctionDeclaration(FunctionDeclaration& node) { PrintNodeHeader("FunctionDeclaration", node.location); IncreaseIndent(); PrintKeyValue("name", node.name, Color::BrightCyan); if (node.is_overload) { PrintKeyValue("overload", true); } PrintSignature(node.signature); DecreaseIndent(); } void DebugPrinter::VisitVarDeclaration(VarDeclaration& node) { PrintNodeHeader("VarDeclaration", node.location); IncreaseIndent(); PrintKeyValue("name", node.name, Color::BrightGreen); if (node.type_name) { PrintKeyValue("type", *node.type_name, Color::BrightMagenta); } if (node.initial_value) { PrintExpression(node.initial_value.get(), "initial_value"); } DecreaseIndent(); } void DebugPrinter::VisitStaticDeclaration(StaticDeclaration& node) { PrintNodeHeader("StaticDeclaration", node.location); IncreaseIndent(); PrintKeyValue("name", node.name, Color::BrightGreen); if (node.reference_modifier != ReferenceModifier::kNone) { PrintIndent(); PrintColored("reference: ", Color::Yellow); PrintReferenceModifier(node.reference_modifier); os_ << "\n"; } if (node.type_name) { PrintKeyValue("type", *node.type_name, Color::BrightMagenta); } if (node.initial_value) { PrintExpression(node.initial_value.get(), "initial_value"); } DecreaseIndent(); } void DebugPrinter::VisitGlobalDeclaration(GlobalDeclaration& node) { PrintNodeHeader("GlobalDeclaration", node.location); IncreaseIndent(); PrintKeyValue("name", node.name, Color::BrightGreen); if (node.type_name) { PrintKeyValue("type", *node.type_name, Color::BrightMagenta); } if (node.initial_value) { PrintExpression(node.initial_value.get(), "initial_value"); } DecreaseIndent(); } void DebugPrinter::VisitFieldDeclaration(FieldDeclaration& node) { PrintNodeHeader("FieldDeclaration", node.location); IncreaseIndent(); PrintKeyValue("name", node.name, Color::BrightGreen); if (node.reference_modifier != ReferenceModifier::kNone) { PrintIndent(); PrintColored("reference: ", Color::Yellow); PrintReferenceModifier(node.reference_modifier); os_ << "\n"; } if (node.type_name) { PrintKeyValue("type", *node.type_name, Color::BrightMagenta); } if (node.initial_value) { PrintExpression(node.initial_value.get(), "initial_value"); } DecreaseIndent(); } void DebugPrinter::VisitUnpackPattern(UnpackPattern& node) { PrintNodeHeader("UnpackPattern", node.location); IncreaseIndent(); if (!node.names.empty()) { PrintIndent(); PrintColored("names: ", Color::Yellow); os_ << "["; for (size_t i = 0; i < node.names.size(); ++i) { if (i > 0) os_ << ", "; PrintColored(node.names[i], Color::BrightGreen); } os_ << "]\n"; } DecreaseIndent(); } void DebugPrinter::VisitClassDefinition(ClassDefinition& node) { PrintNodeHeader("ClassDefinition", node.location); IncreaseIndent(); PrintKeyValue("name", node.name, Color::BrightCyan); if (!node.parent_classes.empty()) { PrintIndent(); PrintColored("parents: ", Color::Yellow); os_ << "["; for (size_t i = 0; i < node.parent_classes.size(); ++i) { if (i > 0) os_ << ", "; PrintColored(node.parent_classes[i], Color::BrightCyan); } os_ << "]\n"; } if (!node.members.empty()) { PrintIndent(); PrintColored("members ", Color::Yellow); PrintColored("(" + std::to_string(node.members.size()) + "):\n", Color::Gray); IncreaseIndent(); for (const auto& member : node.members) { if (member) member->Accept(*this); } DecreaseIndent(); } DecreaseIndent(); } void DebugPrinter::VisitClassMember(ClassMember& node) { PrintNodeHeader("ClassMember", node.location); IncreaseIndent(); PrintIndent(); PrintColored("access: ", Color::Yellow); PrintAccessModifier(node.access_modifier); os_ << "\n"; std::visit([this](auto&& member) { if (member) { member->Accept(*this); } }, node.member); DecreaseIndent(); } void DebugPrinter::VisitMethodDeclaration(MethodDeclaration& node) { PrintNodeHeader("MethodDeclaration", node.location); IncreaseIndent(); PrintKeyValue("name", node.name, Color::BrightCyan); if (node.method_type == MethodType::kConstructor) { PrintKeyValue("type", "constructor", Color::Magenta); } else if (node.method_type == MethodType::kDestructor) { PrintKeyValue("type", "destructor", Color::Magenta); } if (node.is_class_method) { PrintKeyValue("class_method", true); } if (node.is_operator_overload) { PrintKeyValue("operator", node.operator_symbol, Color::BrightYellow); } if (node.modifier != MethodModifier::kNone) { PrintIndent(); PrintColored("modifier: ", Color::Yellow); PrintMethodModifier(node.modifier); os_ << "\n"; } PrintSignature(node.signature); if (node.body) { PrintStatement(node.body.get(), "body", true); } DecreaseIndent(); } void DebugPrinter::VisitPropertyDeclaration(PropertyDeclaration& node) { PrintNodeHeader("PropertyDeclaration", node.location); IncreaseIndent(); PrintKeyValue("name", node.name, Color::BrightCyan); if (node.type_name) { PrintKeyValue("type", *node.type_name, Color::BrightMagenta); } if (node.index_value) { PrintKeyValue("index", *node.index_value); } if (node.read_accessor) { PrintKeyValue("read", *node.read_accessor, Color::Green); } if (node.write_accessor) { PrintKeyValue("write", *node.write_accessor, Color::Green); } DecreaseIndent(); } void DebugPrinter::VisitExternalMethodDefinition(ExternalMethodDefinition& node) { PrintNodeHeader("ExternalMethodDefinition", node.location); IncreaseIndent(); PrintKeyValue("class", node.owner_class, Color::BrightCyan); PrintKeyValue("method", node.name, Color::BrightCyan); if (node.method_type == MethodType::kConstructor) { PrintKeyValue("type", "constructor", Color::Magenta); } else if (node.method_type == MethodType::kDestructor) { PrintKeyValue("type", "destructor", Color::Magenta); } if (node.is_class_method) { PrintKeyValue("class_method", true); } if (node.is_operator_overload) { PrintKeyValue("operator", node.operator_symbol, Color::BrightYellow); } if (node.modifier != MethodModifier::kNone) { PrintIndent(); PrintColored("modifier: ", Color::Yellow); PrintMethodModifier(node.modifier); os_ << "\n"; } PrintSignature(node.signature); if (node.body) { PrintStatement(node.body.get(), "body", true); } DecreaseIndent(); } void DebugPrinter::VisitUnitDefinition(UnitDefinition& node) { PrintNodeHeader("UnitDefinition", node.location); IncreaseIndent(); PrintKeyValue("name", node.name, Color::BrightCyan); if (!node.interface_statements.empty()) { PrintIndent(); PrintColored("interface ", Color::Yellow); PrintColored("(" + std::to_string(node.interface_statements.size()) + "):\n", Color::Gray); IncreaseIndent(); PrintStatements(node.interface_statements); DecreaseIndent(); } if (!node.implementation_statements.empty()) { PrintIndent(); PrintColored("implementation ", Color::Yellow); PrintColored("(" + std::to_string(node.implementation_statements.size()) + "):\n", Color::Gray); IncreaseIndent(); PrintStatements(node.implementation_statements); DecreaseIndent(); } if (!node.initialization_statements.empty()) { PrintIndent(); PrintColored("initialization ", Color::Yellow); PrintColored("(" + std::to_string(node.initialization_statements.size()) + "):\n", Color::Gray); IncreaseIndent(); PrintStatements(node.initialization_statements); DecreaseIndent(); } if (!node.finalization_statements.empty()) { PrintIndent(); PrintColored("finalization ", Color::Yellow); PrintColored("(" + std::to_string(node.finalization_statements.size()) + "):\n", Color::Gray); IncreaseIndent(); PrintStatements(node.finalization_statements); DecreaseIndent(); } DecreaseIndent(); } void DebugPrinter::VisitTSSQLExpression(TSSQLExpression& node) { PrintNodeHeader("TSSQLExpression", node.location); IncreaseIndent(); const char* 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; } PrintKeyValue("sql_type", type_str, Color::BrightMagenta); PrintKeyValue("raw_sql", node.raw_sql, Color::Green); DecreaseIndent(); } // ===== 便捷函数实现 ===== std::string DebugString(const ASTNode* node, const PrintOptions& opts) { std::ostringstream oss; DebugPrinter printer(oss, opts); 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); 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); 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); } }