From 6aa28f9b2385275c6f95c7fb7b2721423b497f4d Mon Sep 17 00:00:00 2001 From: csh Date: Sat, 25 Oct 2025 23:53:04 +0800 Subject: [PATCH] update test_ast file --- lsp-server/test/test_ast/debug_printer.cpp | 1831 +++++++++++--------- lsp-server/test/test_ast/debug_printer.hpp | 131 +- lsp-server/test/test_ast/test.cpp | 104 +- 3 files changed, 1218 insertions(+), 848 deletions(-) diff --git a/lsp-server/test/test_ast/debug_printer.cpp b/lsp-server/test/test_ast/debug_printer.cpp index 5f9434a..900b981 100644 --- a/lsp-server/test/test_ast/debug_printer.cpp +++ b/lsp-server/test/test_ast/debug_printer.cpp @@ -1,11 +1,19 @@ #include +#include #include "./debug_printer.hpp" namespace lsp::language::ast { - void DebugPrinter::PrintIndent() + // ===== 辅助函数实现 ===== + + const char* DebugPrinter::GetColor(const char* color) const { - os_ << GetIndent(); + 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 @@ -13,219 +21,681 @@ namespace lsp::language::ast 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) { - os_ << "[" << loc.start_line << ":" << loc.start_column - << "-" << loc.end_line << ":" << loc.end_column << "]"; + 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(); - os_ << type_name << " "; - PrintLocation(loc); + + // 打印节点类型 + PrintColored(type_name, Color::BrightCyan); + + // 打印位置 + if (options_.show_location || options_.show_source_code) + { + os_ << " "; + PrintLocation(loc); + PrintSourceSnippet(loc); + } + os_ << "\n"; } - void DebugPrinter::PrintExpression(const Expression* expr) + void DebugPrinter::PrintKeyValue(const std::string& key, const std::string& value, const char* value_color) { - if (!expr) - { - os_ << "(null)"; + if (options_.compact_mode && value.empty()) return; - } - const_cast(expr)->Accept(*this); + + PrintIndent(); + PrintColored(key + ": ", Color::Yellow); + + if (value_color) + PrintColored(value, value_color); + else + os_ << value; + + os_ << "\n"; } - void DebugPrinter::PrintParameter(const Parameter& param) + void DebugPrinter::PrintKeyValue(const std::string& key, int value) { PrintIndent(); - os_ << "parameter: " << param.name; - if (param.is_var) - os_ << " [var]"; - if (param.is_out) - os_ << " [out]"; - os_ << " "; - PrintLocation(param.location); + 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"; - if (param.type_name) + PrintColored("╚═══════════════════════════════════════════════════════════════\n", Color::BrightBlue); + + // 打印错误 + if (!result.errors.empty()) { - IncreaseIndent(); - PrintIndent(); - os_ << "type: " << *param.type_name << "\n"; - DecreaseIndent(); + os_ << "\n"; + PrintColored("Errors:\n", Color::BrightRed); + for (const auto& error : result.errors) + { + PrintError(error); + } + os_ << "\n"; } - if (param.default_value) + // 打印AST + if (result.root) { - IncreaseIndent(); - PrintIndent(); - os_ << "default: "; - PrintExpression(param.default_value.get()); os_ << "\n"; - DecreaseIndent(); + 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(); - os_ << "parameters:\n"; + PrintColored("parameters", Color::Yellow); + PrintColored(" (" + std::to_string(sig.parameters.size()) + "):\n", Color::Gray); + IncreaseIndent(); - for (const auto& param : sig.parameters) - PrintParameter(param); + 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) { - PrintIndent(); - os_ << "return_type: " << *sig.return_type << "\n"; + PrintKeyValue("return_type", *sig.return_type, Color::BrightMagenta); } } - void DebugPrinter::PrintLeftHandSide(const LeftHandSide& lhs) + 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>) - { - if (arg) - arg->Accept(*this); - } - else if constexpr (std::is_same_v>) - { - if (arg) - arg->Accept(*this); - } - else if constexpr (std::is_same_v>) - { - if (arg) - arg->Accept(*this); - } - else if constexpr (std::is_same_v>) - { - if (arg) - arg->Accept(*this); - } - else if constexpr (std::is_same_v>) - { - if (arg) - arg->Accept(*this); - } - else if constexpr (std::is_same_v>) - { - if (arg) - arg->Accept(*this); - } - else if constexpr (std::is_same_v>) - { - if (arg) - arg->Accept(*this); - } - else if constexpr (std::is_same_v>) + 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) { - os_ << GetBinaryOperatorSymbol(op); - } - - void DebugPrinter::PrintReferenceModifier(ReferenceModifier modifier) - { - switch (modifier) - { - case ReferenceModifier::kNone: - os_ << "none"; - break; - case ReferenceModifier::kWeakRef: - os_ << "weakref"; - break; - case ReferenceModifier::kAutoRef: - os_ << "autoref"; - break; - } + PrintColored(GetBinaryOperatorSymbol(op), Color::BrightYellow); } void DebugPrinter::PrintOperator(UnaryOperator op) { + const char* symbol = ""; switch (op) { case UnaryOperator::kPlus: - os_ << "+"; + symbol = "+"; break; case UnaryOperator::kMinus: - os_ << "-"; + symbol = "-"; break; case UnaryOperator::kNot: - os_ << "not"; + symbol = "not"; break; case UnaryOperator::kBitwiseNot: - os_ << ".!"; + symbol = ".!"; break; case UnaryOperator::kDotNot: - os_ << ".!!"; + symbol = ".!!"; break; case UnaryOperator::kMatrixTranspose: - os_ << "`"; + symbol = "`"; break; case UnaryOperator::kDerivative: - os_ << "!"; + symbol = "!"; break; case UnaryOperator::kExprAt: - os_ << "@"; + symbol = "@"; break; case UnaryOperator::kExprRef: - os_ << "&"; + symbol = "&"; break; } + PrintColored(symbol, Color::BrightYellow); } void DebugPrinter::PrintOperator(AssignmentOperator op) { - os_ << GetAssignmentOperatorSymbol(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: - os_ << "number"; + kind_str = "number"; break; case LiteralKind::kString: - os_ << "string"; + kind_str = "string"; + color = Color::Green; break; case LiteralKind::kBoolean: - os_ << "boolean"; + kind_str = "boolean"; break; case LiteralKind::kNil: - os_ << "nil"; + kind_str = "nil"; + color = Color::Gray; break; case LiteralKind::kInfinity: - os_ << "infinity"; + kind_str = "infinity"; break; case LiteralKind::kEllipsis: - os_ << "ellipsis"; + 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(); - PrintIndent(); - os_ << "name: " << node.name << "\n"; + PrintKeyValue("name", node.name, Color::BrightGreen); DecreaseIndent(); } @@ -233,12 +703,25 @@ namespace lsp::language::ast { PrintNodeHeader("Literal", node.location); IncreaseIndent(); + PrintIndent(); - os_ << "kind: "; + PrintColored("kind: ", Color::Yellow); PrintLiteralKind(node.literal_kind); os_ << "\n"; + PrintIndent(); - os_ << "value: " << node.value << "\n"; + 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(); } @@ -248,21 +731,12 @@ namespace lsp::language::ast IncreaseIndent(); PrintIndent(); - os_ << "operator: "; + PrintColored("operator: ", Color::Yellow); PrintOperator(node.op); os_ << "\n"; - PrintIndent(); - os_ << "left:\n"; - IncreaseIndent(); - PrintExpression(node.left.get()); - DecreaseIndent(); - - PrintIndent(); - os_ << "right:\n"; - IncreaseIndent(); - PrintExpression(node.right.get()); - DecreaseIndent(); + PrintExpression(node.left.get(), "left", false); + PrintExpression(node.right.get(), "right", true); DecreaseIndent(); } @@ -272,35 +746,29 @@ namespace lsp::language::ast PrintNodeHeader("ComparisonExpression", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "left:\n"; - IncreaseIndent(); - PrintExpression(node.left.get()); - DecreaseIndent(); + PrintExpression(node.left.get(), "left", false); if (!node.comparisons.empty()) { PrintIndent(); - os_ << "comparisons:\n"; + 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(); - os_ << "[" << i << "] operator: "; + PrintColored("[" + std::to_string(i) + "] ", Color::Gray); PrintOperator(comp.op); os_ << "\n"; - IncreaseIndent(); - PrintIndent(); - os_ << "right:\n"; - IncreaseIndent(); if (comp.right) + { + IncreaseIndent(); PrintExpression(comp.right.get()); - else - os_ << "(null)\n"; - DecreaseIndent(); - DecreaseIndent(); + DecreaseIndent(); + } } DecreaseIndent(); } @@ -314,15 +782,11 @@ namespace lsp::language::ast IncreaseIndent(); PrintIndent(); - os_ << "operator: "; + PrintColored("operator: ", Color::Yellow); PrintOperator(node.op); os_ << "\n"; - PrintIndent(); - os_ << "argument:\n"; - IncreaseIndent(); - PrintExpression(node.argument.get()); - DecreaseIndent(); + PrintExpression(node.argument.get(), "argument", true); DecreaseIndent(); } @@ -332,26 +796,9 @@ namespace lsp::language::ast PrintNodeHeader("TernaryExpression", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "condition:\n"; - IncreaseIndent(); - PrintExpression(node.condition.get()); - DecreaseIndent(); - - PrintIndent(); - os_ << "consequence:\n"; - IncreaseIndent(); - if (node.consequence) - PrintExpression(node.consequence.get()); - else - os_ << "(null)\n"; - DecreaseIndent(); - - PrintIndent(); - os_ << "alternative:\n"; - IncreaseIndent(); - PrintExpression(node.alternative.get()); - DecreaseIndent(); + PrintExpression(node.condition.get(), "condition", false); + PrintExpression(node.consequence.get(), "consequence", false); + PrintExpression(node.alternative.get(), "alternative", true); DecreaseIndent(); } @@ -361,36 +808,52 @@ namespace lsp::language::ast PrintNodeHeader("CallExpression", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "callee:\n"; - IncreaseIndent(); - PrintExpression(node.callee.get()); - DecreaseIndent(); + bool has_arguments = !node.arguments.empty(); + PrintExpression(node.callee.get(), "callee", !has_arguments); - if (!node.arguments.empty()) + if (has_arguments) { - for (const auto& arg : node.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) { - PrintIndent(); - os_ << "argument:\n"; + 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) { - IncreaseIndent(); - os_ << "named(" << &arg.name << "): "; - DecreaseIndent(); - os_ << "\n"; + 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(); - PrintExpression(arg.value.get()); + arg.value->Accept(*this); DecreaseIndent(); } - else + + if (options_.use_tree_chars) { - os_ << "(null)\n"; + is_last_child_stack_.pop_back(); } } + DecreaseIndent(); } DecreaseIndent(); @@ -401,14 +864,8 @@ namespace lsp::language::ast PrintNodeHeader("AttributeExpression", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "object:\n"; - IncreaseIndent(); - PrintExpression(node.object.get()); - DecreaseIndent(); - - PrintIndent(); - os_ << "attribute: " << node.attribute << "\n"; + PrintExpression(node.object.get(), "object", false); + PrintKeyValue("attribute", node.attribute, Color::BrightGreen); DecreaseIndent(); } @@ -418,64 +875,45 @@ namespace lsp::language::ast PrintNodeHeader("SubscriptExpression", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "value:\n"; - IncreaseIndent(); - PrintExpression(node.value.get()); - DecreaseIndent(); + PrintExpression(node.value.get(), "value"); if (!node.indices.empty()) { PrintIndent(); - os_ << "indices:\n"; + 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(); - os_ << "[" << i << "] "; + 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_ << "empty_slice\n"; + os_ << " " << GetColor(Color::Cyan) << "[empty]" << GetColor(Color::Reset); } - else if (idx.is_slice) + os_ << "\n"; + + IncreaseIndent(); + if (idx.start) { - os_ << "slice:\n"; - IncreaseIndent(); - if (idx.start) - { - PrintIndent(); - os_ << "start:\n"; - IncreaseIndent(); - PrintExpression(idx.start.get()); - DecreaseIndent(); - } - if (idx.end) - { - PrintIndent(); - os_ << "end:\n"; - IncreaseIndent(); - PrintExpression(idx.end.get()); - DecreaseIndent(); - } - if (idx.step) - { - PrintIndent(); - os_ << "step:\n"; - IncreaseIndent(); - PrintExpression(idx.step.get()); - DecreaseIndent(); - } - DecreaseIndent(); + PrintExpression(idx.start.get(), "start"); } - else if (idx.start) + if (idx.end) { - os_ << "index:\n"; - IncreaseIndent(); - PrintExpression(idx.start.get()); - DecreaseIndent(); + PrintExpression(idx.end.get(), "end"); } + if (idx.step) + { + PrintExpression(idx.step.get(), "step"); + } + DecreaseIndent(); } DecreaseIndent(); } @@ -491,46 +929,32 @@ namespace lsp::language::ast if (!node.elements.empty()) { PrintIndent(); - os_ << "elements:\n"; + 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(); - os_ << "[" << i << "] "; + PrintColored("[" + std::to_string(i) + "]", Color::Gray); if (elem.is_nested) { - os_ << "nested:\n"; - IncreaseIndent(); - if (elem.value) - PrintExpression(elem.value.get()); - DecreaseIndent(); + os_ << " " << GetColor(Color::Cyan) << "[nested]" << GetColor(Color::Reset); } - else if (elem.key) + os_ << "\n"; + + IncreaseIndent(); + if (elem.key) { - os_ << "key_value:\n"; - IncreaseIndent(); - PrintIndent(); - os_ << "key:\n"; - IncreaseIndent(); - PrintExpression(elem.key.get()); - DecreaseIndent(); - PrintIndent(); - os_ << "value:\n"; - IncreaseIndent(); - if (elem.value) - PrintExpression(elem.value.get()); - DecreaseIndent(); - DecreaseIndent(); + PrintExpression(elem.key.get(), "key"); } - else if (elem.value) + if (elem.value) { - os_ << "value:\n"; - IncreaseIndent(); - PrintExpression(elem.value.get()); - DecreaseIndent(); + PrintExpression(elem.value.get(), "value"); } + DecreaseIndent(); } DecreaseIndent(); } @@ -540,18 +964,15 @@ namespace lsp::language::ast void DebugPrinter::VisitAnonymousFunctionExpression(AnonymousFunctionExpression& node) { - PrintNodeHeader("AnonymousFunctionExpression", node.location); + PrintNodeHeader("AnonymousFunction", node.location); IncreaseIndent(); PrintSignature(node.signature); if (node.body) { - PrintIndent(); - os_ << "body:\n"; - IncreaseIndent(); - node.body->Accept(*this); - DecreaseIndent(); + PrintStatement(node.body.get(), "body", true); + PrintStatement(node.body.get(), "body", true); } DecreaseIndent(); @@ -559,61 +980,41 @@ namespace lsp::language::ast void DebugPrinter::VisitPrefixIncrementExpression(PrefixIncrementExpression& node) { - PrintNodeHeader("PrefixIncrementExpression", node.location); + PrintNodeHeader("PrefixIncrement", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "argument:\n"; - IncreaseIndent(); - PrintExpression(node.argument.get()); - DecreaseIndent(); + PrintExpression(node.argument.get(), "argument", true); DecreaseIndent(); } void DebugPrinter::VisitPrefixDecrementExpression(PrefixDecrementExpression& node) { - PrintNodeHeader("PrefixDecrementExpression", node.location); + PrintNodeHeader("PrefixDecrement", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "argument:\n"; - IncreaseIndent(); - PrintExpression(node.argument.get()); - DecreaseIndent(); + PrintExpression(node.argument.get(), "argument", true); DecreaseIndent(); } void DebugPrinter::VisitPostfixIncrementExpression(PostfixIncrementExpression& node) { - PrintNodeHeader("PostfixIncrementExpression", node.location); + PrintNodeHeader("PostfixIncrement", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "argument:\n"; - IncreaseIndent(); - PrintExpression(node.argument.get()); - DecreaseIndent(); + PrintExpression(node.argument.get(), "argument", true); DecreaseIndent(); } void DebugPrinter::VisitPostfixDecrementExpression(PostfixDecrementExpression& node) { - PrintNodeHeader("PostfixDecrementExpression", node.location); + PrintNodeHeader("PostfixDecrement", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "argument:\n"; - IncreaseIndent(); - PrintExpression(node.argument.get()); - DecreaseIndent(); + PrintExpression(node.argument.get(), "argument", true); DecreaseIndent(); } void DebugPrinter::VisitFunctionPointerExpression(FunctionPointerExpression& node) { - PrintNodeHeader("FunctionPointerExpression", node.location); + PrintNodeHeader("FunctionPointer", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "argument:\n"; - IncreaseIndent(); - PrintExpression(node.argument.get()); - DecreaseIndent(); + PrintExpression(node.argument.get(), "argument", true); DecreaseIndent(); } @@ -623,21 +1024,12 @@ namespace lsp::language::ast IncreaseIndent(); PrintIndent(); - os_ << "operator: "; + PrintColored("operator: ", Color::Yellow); PrintOperator(node.op); os_ << "\n"; - PrintIndent(); - os_ << "left:\n"; - IncreaseIndent(); - PrintLeftHandSide(node.left); - DecreaseIndent(); - - PrintIndent(); - os_ << "right:\n"; - IncreaseIndent(); - PrintExpression(node.right.get()); - DecreaseIndent(); + PrintLeftHandSide(node.left, "left", false); + PrintExpression(node.right.get(), "right", true); DecreaseIndent(); } @@ -646,8 +1038,7 @@ namespace lsp::language::ast { PrintNodeHeader("ExpressionStatement", node.location); IncreaseIndent(); - if (node.expression) - PrintExpression(node.expression.get()); + PrintExpression(node.expression.get(), "", true); DecreaseIndent(); } @@ -659,12 +1050,26 @@ namespace lsp::language::ast if (!node.declarations.empty()) { PrintIndent(); - os_ << "declarations:\n"; + PrintColored("declarations ", Color::Yellow); + PrintColored("(" + std::to_string(node.declarations.size()) + "):\n", Color::Gray); + IncreaseIndent(); - for (const auto& decl : node.declarations) + for (size_t i = 0; i < node.declarations.size(); ++i) { - if (decl) - decl->Accept(*this); + 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(); } @@ -680,12 +1085,26 @@ namespace lsp::language::ast if (!node.declarations.empty()) { PrintIndent(); - os_ << "declarations:\n"; + PrintColored("declarations ", Color::Yellow); + PrintColored("(" + std::to_string(node.declarations.size()) + "):\n", Color::Gray); + IncreaseIndent(); - for (const auto& decl : node.declarations) + for (size_t i = 0; i < node.declarations.size(); ++i) { - if (decl) - decl->Accept(*this); + 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(); } @@ -701,12 +1120,26 @@ namespace lsp::language::ast if (!node.declarations.empty()) { PrintIndent(); - os_ << "declarations:\n"; + PrintColored("declarations ", Color::Yellow); + PrintColored("(" + std::to_string(node.declarations.size()) + "):\n", Color::Gray); + IncreaseIndent(); - for (const auto& decl : node.declarations) + for (size_t i = 0; i < node.declarations.size(); ++i) { - if (decl) - decl->Accept(*this); + 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(); } @@ -719,20 +1152,17 @@ namespace lsp::language::ast PrintNodeHeader("ConstStatement", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "name: " << node.name << "\n"; + PrintKeyValue("name", node.name, Color::BrightGreen); if (node.type_name) { - PrintIndent(); - os_ << "type: " << *node.type_name << "\n"; + PrintKeyValue("type", *node.type_name, Color::BrightMagenta); } - PrintIndent(); - os_ << "value:\n"; - IncreaseIndent(); - PrintExpression(node.value.get()); - DecreaseIndent(); + if (node.value) + { + PrintExpression(node.value.get(), "value", true); + } DecreaseIndent(); } @@ -743,21 +1173,12 @@ namespace lsp::language::ast IncreaseIndent(); PrintIndent(); - os_ << "operator: "; + PrintColored("operator: ", Color::Yellow); PrintOperator(node.op); os_ << "\n"; - PrintIndent(); - os_ << "left:\n"; - IncreaseIndent(); - PrintLeftHandSide(node.left); - DecreaseIndent(); - - PrintIndent(); - os_ << "right:\n"; - IncreaseIndent(); - PrintExpression(node.right.get()); - DecreaseIndent(); + PrintLeftHandSide(node.left, "left", false); + PrintExpression(node.right.get(), "right", true); DecreaseIndent(); } @@ -765,27 +1186,13 @@ namespace lsp::language::ast void DebugPrinter::VisitBlockStatement(BlockStatement& node) { PrintNodeHeader("BlockStatement", node.location); - IncreaseIndent(); if (!node.statements.empty()) { - PrintIndent(); - os_ << "statements: (" << node.statements.size() << ")\n"; IncreaseIndent(); - for (const auto& stmt : node.statements) - { - if (stmt) - stmt->Accept(*this); - } + PrintStatements(node.statements); DecreaseIndent(); } - else - { - PrintIndent(); - os_ << "(empty block)\n"; - } - - DecreaseIndent(); } void DebugPrinter::VisitIfStatement(IfStatement& node) @@ -793,36 +1200,31 @@ namespace lsp::language::ast PrintNodeHeader("IfStatement", node.location); IncreaseIndent(); - for (size_t i = 0; i < node.branches.size(); ++i) + if (!node.branches.empty()) { - const auto& branch = node.branches[i]; - PrintIndent(); - if (i == 0) - os_ << "if branch:\n"; - else if (branch.condition) - os_ << "else if branch:\n"; - else - os_ << "else branch:\n"; + PrintColored("branches ", Color::Yellow); + PrintColored("(" + std::to_string(node.branches.size()) + "):\n", Color::Gray); IncreaseIndent(); - - if (branch.condition) + for (size_t i = 0; i < node.branches.size(); ++i) { + const auto& branch = node.branches[i]; PrintIndent(); - os_ << "condition:\n"; + PrintColored("[" + std::to_string(i) + "]", Color::Gray); + os_ << "\n"; + IncreaseIndent(); - PrintExpression(branch.condition.get()); + if (branch.condition) + { + PrintExpression(branch.condition.get(), "condition"); + } + if (branch.body) + { + PrintStatement(branch.body.get(), "body"); + } DecreaseIndent(); } - - PrintIndent(); - os_ << "body:\n"; - IncreaseIndent(); - if (branch.body) - branch.body->Accept(*this); - DecreaseIndent(); - DecreaseIndent(); } @@ -834,24 +1236,21 @@ namespace lsp::language::ast PrintNodeHeader("ForInStatement", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "key: " << node.key << "\n"; + if (!node.key.empty()) + { + PrintKeyValue("key", node.key, Color::BrightGreen); + } + if (!node.value.empty()) + { + PrintKeyValue("value", node.value, Color::BrightGreen); + } - PrintIndent(); - os_ << "value: " << node.value << "\n"; + PrintExpression(node.collection.get(), "collection", false); - PrintIndent(); - os_ << "collection:\n"; - IncreaseIndent(); - PrintExpression(node.collection.get()); - DecreaseIndent(); - - PrintIndent(); - os_ << "body:\n"; - IncreaseIndent(); if (node.body) - node.body->Accept(*this); - DecreaseIndent(); + { + PrintStatement(node.body.get(), "body", true); + } DecreaseIndent(); } @@ -861,30 +1260,20 @@ namespace lsp::language::ast PrintNodeHeader("ForToStatement", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "counter: " << node.counter << "\n"; + PrintKeyValue("counter", node.counter, Color::BrightGreen); - PrintIndent(); - os_ << "direction: " << (node.is_downto ? "downto" : "to") << "\n"; + if (node.is_downto) + { + PrintKeyValue("direction", "downto", Color::Cyan); + } - PrintIndent(); - os_ << "start:\n"; - IncreaseIndent(); - PrintExpression(node.start.get()); - DecreaseIndent(); + PrintExpression(node.start.get(), "start", false); + PrintExpression(node.end.get(), "end", false); - PrintIndent(); - os_ << "end:\n"; - IncreaseIndent(); - PrintExpression(node.end.get()); - DecreaseIndent(); - - PrintIndent(); - os_ << "body:\n"; - IncreaseIndent(); if (node.body) - node.body->Accept(*this); - DecreaseIndent(); + { + PrintStatement(node.body.get(), "body", true); + } DecreaseIndent(); } @@ -894,18 +1283,12 @@ namespace lsp::language::ast PrintNodeHeader("WhileStatement", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "condition:\n"; - IncreaseIndent(); - PrintExpression(node.condition.get()); - DecreaseIndent(); + PrintExpression(node.condition.get(), "condition", false); - PrintIndent(); - os_ << "body:\n"; - IncreaseIndent(); if (node.body) - node.body->Accept(*this); - DecreaseIndent(); + { + PrintStatement(node.body.get(), "body", true); + } DecreaseIndent(); } @@ -915,21 +1298,18 @@ namespace lsp::language::ast PrintNodeHeader("RepeatStatement", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "body: (" << node.body.size() << " statements)\n"; - IncreaseIndent(); - for (const auto& stmt : node.body) + if (!node.body.empty()) { - if (stmt) - stmt->Accept(*this); - } - DecreaseIndent(); + PrintIndent(); + PrintColored("body ", Color::Yellow); + PrintColored("(" + std::to_string(node.body.size()) + "):\n", Color::Gray); - PrintIndent(); - os_ << "condition:\n"; - IncreaseIndent(); - PrintExpression(node.condition.get()); - DecreaseIndent(); + IncreaseIndent(); + PrintStatements(node.body); + DecreaseIndent(); + } + + PrintExpression(node.condition.get(), "condition", true); DecreaseIndent(); } @@ -939,43 +1319,42 @@ namespace lsp::language::ast PrintNodeHeader("CaseStatement", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "discriminant:\n"; - IncreaseIndent(); - PrintExpression(node.discriminant.get()); - DecreaseIndent(); + PrintExpression(node.discriminant.get(), "discriminant"); if (!node.branches.empty()) { PrintIndent(); - os_ << "branches:\n"; + 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(); - os_ << "branch " << i << ":\n"; - IncreaseIndent(); + PrintColored("[" + std::to_string(i) + "]", Color::Gray); + os_ << "\n"; + IncreaseIndent(); if (!branch.values.empty()) { PrintIndent(); - os_ << "values:\n"; + PrintColored("values ", Color::Yellow); + PrintColored("(" + std::to_string(branch.values.size()) + "):\n", Color::Gray); + IncreaseIndent(); for (const auto& val : branch.values) { - PrintExpression(val.get()); + if (val) + val->Accept(*this); } DecreaseIndent(); } - PrintIndent(); - os_ << "body:\n"; - IncreaseIndent(); if (branch.body) - branch.body->Accept(*this); - DecreaseIndent(); - + { + PrintStatement(branch.body.get(), "body"); + } DecreaseIndent(); } DecreaseIndent(); @@ -983,11 +1362,7 @@ namespace lsp::language::ast if (node.default_case) { - PrintIndent(); - os_ << "default:\n"; - IncreaseIndent(); - node.default_case->Accept(*this); - DecreaseIndent(); + PrintStatement(node.default_case.get(), "default_case"); } DecreaseIndent(); @@ -998,19 +1373,15 @@ namespace lsp::language::ast PrintNodeHeader("TryStatement", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "try:\n"; - IncreaseIndent(); if (node.try_body) - node.try_body->Accept(*this); - DecreaseIndent(); + { + PrintStatement(node.try_body.get(), "try_body"); + } - PrintIndent(); - os_ << "except:\n"; - IncreaseIndent(); if (node.except_body) - node.except_body->Accept(*this); - DecreaseIndent(); + { + PrintStatement(node.except_body.get(), "except_body"); + } DecreaseIndent(); } @@ -1032,11 +1403,7 @@ namespace lsp::language::ast if (node.value) { IncreaseIndent(); - PrintIndent(); - os_ << "value:\n"; - IncreaseIndent(); - PrintExpression(node.value.get()); - DecreaseIndent(); + PrintExpression(node.value.get(), "value", true); DecreaseIndent(); } } @@ -1045,15 +1412,21 @@ namespace lsp::language::ast { PrintNodeHeader("UsesStatement", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "module: ["; - for (size_t i = 0; i < node.modules.size(); i++) + + if (!node.units.empty()) { - if (i > 0) - os_ << ", "; - os_ << node.modules[i]; + 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"; } - os_ << "]\n"; + DecreaseIndent(); } @@ -1062,21 +1435,18 @@ namespace lsp::language::ast PrintNodeHeader("FunctionDefinition", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "name: " << node.name; + PrintKeyValue("name", node.name, Color::BrightCyan); + if (node.is_overload) - os_ << " [overload]"; - os_ << "\n"; + { + PrintKeyValue("overload", true); + } PrintSignature(node.signature); if (node.body) { - PrintIndent(); - os_ << "body:\n"; - IncreaseIndent(); - node.body->Accept(*this); - DecreaseIndent(); + PrintStatement(node.body.get(), "body", true); } DecreaseIndent(); @@ -1087,11 +1457,13 @@ namespace lsp::language::ast PrintNodeHeader("FunctionDeclaration", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "name: " << node.name; + PrintKeyValue("name", node.name, Color::BrightCyan); + if (node.is_overload) - os_ << " [overload]"; - os_ << "\n"; + { + PrintKeyValue("overload", true); + } + PrintSignature(node.signature); DecreaseIndent(); @@ -1102,22 +1474,16 @@ namespace lsp::language::ast PrintNodeHeader("VarDeclaration", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "name: " << node.name << "\n"; + PrintKeyValue("name", node.name, Color::BrightGreen); if (node.type_name) { - PrintIndent(); - os_ << "type: " << *node.type_name << "\n"; // 修正:使用 * 而不是 & + PrintKeyValue("type", *node.type_name, Color::BrightMagenta); } if (node.initial_value) { - PrintIndent(); - os_ << "initial_value:\n"; - IncreaseIndent(); - PrintExpression(node.initial_value.get()); - DecreaseIndent(); + PrintExpression(node.initial_value.get(), "initial_value"); } DecreaseIndent(); @@ -1128,31 +1494,24 @@ namespace lsp::language::ast PrintNodeHeader("StaticDeclaration", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "name: " << node.name << "\n"; + PrintKeyValue("name", node.name, Color::BrightGreen); - // 添加引用修饰符打印 if (node.reference_modifier != ReferenceModifier::kNone) { PrintIndent(); - os_ << "reference_modifier: "; + PrintColored("reference: ", Color::Yellow); PrintReferenceModifier(node.reference_modifier); os_ << "\n"; } if (node.type_name) { - PrintIndent(); - os_ << "type: " << *node.type_name << "\n"; // 修正:使用 * 而不是 & + PrintKeyValue("type", *node.type_name, Color::BrightMagenta); } if (node.initial_value) { - PrintIndent(); - os_ << "initial_value:\n"; - IncreaseIndent(); - PrintExpression(node.initial_value.get()); - DecreaseIndent(); + PrintExpression(node.initial_value.get(), "initial_value"); } DecreaseIndent(); @@ -1163,22 +1522,16 @@ namespace lsp::language::ast PrintNodeHeader("GlobalDeclaration", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "name: " << node.name << "\n"; + PrintKeyValue("name", node.name, Color::BrightGreen); if (node.type_name) { - PrintIndent(); - os_ << "type: " << *node.type_name << "\n"; + PrintKeyValue("type", *node.type_name, Color::BrightMagenta); } if (node.initial_value) { - PrintIndent(); - os_ << "initial_value:\n"; - IncreaseIndent(); - PrintExpression(node.initial_value.get()); - DecreaseIndent(); + PrintExpression(node.initial_value.get(), "initial_value"); } DecreaseIndent(); @@ -1189,31 +1542,24 @@ namespace lsp::language::ast PrintNodeHeader("FieldDeclaration", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "name: " << node.name << "\n"; + PrintKeyValue("name", node.name, Color::BrightGreen); - // 添加引用修饰符打印 if (node.reference_modifier != ReferenceModifier::kNone) { PrintIndent(); - os_ << "reference_modifier: "; + PrintColored("reference: ", Color::Yellow); PrintReferenceModifier(node.reference_modifier); os_ << "\n"; } if (node.type_name) { - PrintIndent(); - os_ << "type: " << *node.type_name << "\n"; // 修正:使用 * 而不是 & + PrintKeyValue("type", *node.type_name, Color::BrightMagenta); } if (node.initial_value) { - PrintIndent(); - os_ << "initial_value:\n"; - IncreaseIndent(); - PrintExpression(node.initial_value.get()); - DecreaseIndent(); + PrintExpression(node.initial_value.get(), "initial_value"); } DecreaseIndent(); @@ -1224,185 +1570,18 @@ namespace lsp::language::ast PrintNodeHeader("UnpackPattern", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "names: ["; - for (size_t i = 0; i < node.names.size(); ++i) - { - if (i > 0) - os_ << ", "; - os_ << node.names[i]; - } - os_ << "]\n"; - - DecreaseIndent(); - } - - void DebugPrinter::VisitTSSQLExpression(TSSQLExpression& node) - { - PrintNodeHeader("TSSQLExpression", node.location); - IncreaseIndent(); - - PrintIndent(); - os_ << "sql_type: "; - switch (node.sql_type) - { - case TSSQLExpressionType::kSelect: - os_ << "SELECT"; - break; - case TSSQLExpressionType::kSSelect: - os_ << "SSELECT"; - break; - case TSSQLExpressionType::kVSelect: - os_ << "VSELECT"; - break; - case TSSQLExpressionType::kMSelect: - os_ << "MSELECT"; - break; - case TSSQLExpressionType::kUpdate: - os_ << "UPDATE"; - break; - case TSSQLExpressionType::kDelete: - os_ << "DELETE"; - break; - case TSSQLExpressionType::kInsert: - os_ << "INSERT"; - break; - } - os_ << "\n"; - - PrintIndent(); - os_ << "raw_sql: " << node.raw_sql << "\n"; - - DecreaseIndent(); - } - - void DebugPrinter::PrintError(const ParseError& error) - { - PrintIndent(); - os_ << "ERROR "; - PrintLocation(error.location); - os_ << " [" << error.node_type << "]: " << error.message << "\n"; - } - - void DebugPrinter::Print(const ASTNode* node) - { - if (!node) + if (!node.names.empty()) { PrintIndent(); - os_ << "(null node)\n"; - return; - } - - const_cast(*node).Accept(*this); - } - - void DebugPrinter::PrintStatements(const std::vector& statements) - { - for (const auto& stmt : statements) - { - if (stmt) - Print(stmt.get()); - } - } - - void DebugPrinter::PrintParseResult(const ParseResult& result) - { - os_ << "==================== Parse Result ====================\n"; - os_ << "Total Statements: " << result.statements.size() << "\n"; - os_ << "Total Errors: " << result.errors.size() << "\n"; - os_ << "\n"; - - if (!result.errors.empty()) - { - os_ << "Errors:\n"; - IncreaseIndent(); - for (const auto& error : result.errors) + PrintColored("names: ", Color::Yellow); + os_ << "["; + for (size_t i = 0; i < node.names.size(); ++i) { - PrintError(error); + if (i > 0) + os_ << ", "; + PrintColored(node.names[i], Color::BrightGreen); } - DecreaseIndent(); - os_ << "\n"; - } - - if (!result.statements.empty()) - { - os_ << "AST Statements:\n"; - IncreaseIndent(); - PrintStatements(result.statements); - DecreaseIndent(); - } - - os_ << "==================== End ====================\n"; - } - - void DebugPrinter::VisitUnitDefinition(UnitDefinition& node) - { - PrintNodeHeader("UnitDefinition", node.location); - IncreaseIndent(); - - PrintIndent(); - os_ << "name: " << node.name << "\n"; - - if (!node.interface_statements.empty()) - { - PrintIndent(); - os_ << "interface: (" << node.interface_statements.size() << " statements)\n"; - IncreaseIndent(); - for (const auto& stmt : node.interface_statements) - { - if (stmt) - stmt->Accept(*this); - } - DecreaseIndent(); - } - else - { - PrintIndent(); - os_ << "interface: (empty)\n"; - } - - if (!node.implementation_statements.empty()) - { - PrintIndent(); - os_ << "implementation: (" << node.implementation_statements.size() << " statements)\n"; - IncreaseIndent(); - for (const auto& stmt : node.implementation_statements) - { - if (stmt) - stmt->Accept(*this); - } - DecreaseIndent(); - } - else - { - PrintIndent(); - os_ << "implementation: (empty)\n"; - } - - if (!node.initialization_statements.empty()) - { - PrintIndent(); - os_ << "initialization: (" << node.initialization_statements.size() << " statements)\n"; - IncreaseIndent(); - for (const auto& stmt : node.initialization_statements) - { - if (stmt) - stmt->Accept(*this); - } - DecreaseIndent(); - } - - if (!node.finalization_statements.empty()) - { - PrintIndent(); - os_ << "finalization: (" << node.finalization_statements.size() << " statements)\n"; - IncreaseIndent(); - for (const auto& stmt : node.finalization_statements) - { - if (stmt) - stmt->Accept(*this); - } - DecreaseIndent(); + os_ << "]\n"; } DecreaseIndent(); @@ -1413,18 +1592,18 @@ namespace lsp::language::ast PrintNodeHeader("ClassDefinition", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "name: " << node.name << "\n"; + PrintKeyValue("name", node.name, Color::BrightCyan); if (!node.parent_classes.empty()) { PrintIndent(); - os_ << "parents: ["; + PrintColored("parents: ", Color::Yellow); + os_ << "["; for (size_t i = 0; i < node.parent_classes.size(); ++i) { if (i > 0) os_ << ", "; - os_ << node.parent_classes[i]; + PrintColored(node.parent_classes[i], Color::BrightCyan); } os_ << "]\n"; } @@ -1432,7 +1611,9 @@ namespace lsp::language::ast if (!node.members.empty()) { PrintIndent(); - os_ << "members: (" << node.members.size() << ")\n"; + PrintColored("members ", Color::Yellow); + PrintColored("(" + std::to_string(node.members.size()) + "):\n", Color::Gray); + IncreaseIndent(); for (const auto& member : node.members) { @@ -1441,11 +1622,6 @@ namespace lsp::language::ast } DecreaseIndent(); } - else - { - PrintIndent(); - os_ << "members: (empty)\n"; - } DecreaseIndent(); } @@ -1456,29 +1632,19 @@ namespace lsp::language::ast IncreaseIndent(); PrintIndent(); - os_ << "access: "; + PrintColored("access: ", Color::Yellow); PrintAccessModifier(node.access_modifier); os_ << "\n"; - PrintIndent(); - os_ << "member:\n"; - IncreaseIndent(); - std::visit([this](auto&& member) { if (member) { member->Accept(*this); } - else - { - PrintIndent(); - os_ << "(null member)\n"; - } }, node.member); DecreaseIndent(); - DecreaseIndent(); } void DebugPrinter::VisitMethodDeclaration(MethodDeclaration& node) @@ -1486,24 +1652,31 @@ namespace lsp::language::ast PrintNodeHeader("MethodDeclaration", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "name: " << node.name; + PrintKeyValue("name", node.name, Color::BrightCyan); if (node.method_type == MethodType::kConstructor) - os_ << " [constructor]"; + { + PrintKeyValue("type", "constructor", Color::Magenta); + } else if (node.method_type == MethodType::kDestructor) - os_ << " [destructor]"; + { + PrintKeyValue("type", "destructor", Color::Magenta); + } if (node.is_class_method) - os_ << " [class]"; + { + PrintKeyValue("class_method", true); + } + if (node.is_operator_overload) - os_ << " [operator: " << node.operator_symbol << "]"; - os_ << "\n"; + { + PrintKeyValue("operator", node.operator_symbol, Color::BrightYellow); + } if (node.modifier != MethodModifier::kNone) { PrintIndent(); - os_ << "modifier: "; + PrintColored("modifier: ", Color::Yellow); PrintMethodModifier(node.modifier); os_ << "\n"; } @@ -1512,16 +1685,7 @@ namespace lsp::language::ast if (node.body) { - PrintIndent(); - os_ << "body:\n"; - IncreaseIndent(); - node.body->Accept(*this); - DecreaseIndent(); - } - else - { - PrintIndent(); - os_ << "body: (none - declaration only)\n"; + PrintStatement(node.body.get(), "body", true); } DecreaseIndent(); @@ -1532,31 +1696,26 @@ namespace lsp::language::ast PrintNodeHeader("PropertyDeclaration", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "name: " << node.name << "\n"; + PrintKeyValue("name", node.name, Color::BrightCyan); if (node.type_name) { - PrintIndent(); - os_ << "type: " << *node.type_name << "\n"; + PrintKeyValue("type", *node.type_name, Color::BrightMagenta); } if (node.index_value) { - PrintIndent(); - os_ << "index: " << *node.index_value << "\n"; + PrintKeyValue("index", *node.index_value); } if (node.read_accessor) { - PrintIndent(); - os_ << "read: " << *node.read_accessor << "\n"; + PrintKeyValue("read", *node.read_accessor, Color::Green); } if (node.write_accessor) { - PrintIndent(); - os_ << "write: " << *node.write_accessor << "\n"; + PrintKeyValue("write", *node.write_accessor, Color::Green); } DecreaseIndent(); @@ -1567,26 +1726,32 @@ namespace lsp::language::ast PrintNodeHeader("ExternalMethodDefinition", node.location); IncreaseIndent(); - PrintIndent(); - os_ << "class: " << node.owner_class << "\n"; - - PrintIndent(); - os_ << "method: " << node.name; + PrintKeyValue("class", node.owner_class, Color::BrightCyan); + PrintKeyValue("method", node.name, Color::BrightCyan); if (node.method_type == MethodType::kConstructor) - os_ << " [constructor]"; + { + PrintKeyValue("type", "constructor", Color::Magenta); + } else if (node.method_type == MethodType::kDestructor) - os_ << " [destructor]"; + { + PrintKeyValue("type", "destructor", Color::Magenta); + } + if (node.is_class_method) - os_ << " [class]"; + { + PrintKeyValue("class_method", true); + } + if (node.is_operator_overload) - os_ << " [operator: " << node.operator_symbol << "]"; - os_ << "\n"; + { + PrintKeyValue("operator", node.operator_symbol, Color::BrightYellow); + } if (node.modifier != MethodModifier::kNone) { PrintIndent(); - os_ << "modifier: "; + PrintColored("modifier: ", Color::Yellow); PrintMethodModifier(node.modifier); os_ << "\n"; } @@ -1594,77 +1759,145 @@ namespace lsp::language::ast 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(); - os_ << "body:\n"; + PrintColored("interface ", Color::Yellow); + PrintColored("(" + std::to_string(node.interface_statements.size()) + "):\n", Color::Gray); + IncreaseIndent(); - node.body->Accept(*this); + 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::PrintAccessModifier(AccessModifier modifier) + void DebugPrinter::VisitTSSQLExpression(TSSQLExpression& node) { - switch (modifier) + PrintNodeHeader("TSSQLExpression", node.location); + IncreaseIndent(); + + const char* type_str = ""; + switch (node.sql_type) { - case AccessModifier::kPublic: - os_ << "public"; + case TSSQLExpressionType::kSelect: + type_str = "SELECT"; break; - case AccessModifier::kProtected: - os_ << "protected"; + case TSSQLExpressionType::kSSelect: + type_str = "SSELECT"; break; - case AccessModifier::kPrivate: - os_ << "private"; + 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(); } - void DebugPrinter::PrintMethodModifier(MethodModifier modifier) - { - switch (modifier) - { - case MethodModifier::kNone: - os_ << "none"; - break; - case MethodModifier::kVirtual: - os_ << "virtual"; - break; - case MethodModifier::kOverride: - os_ << "override"; - break; - case MethodModifier::kOverload: - os_ << "overload"; - break; - } - } + // ===== 便捷函数实现 ===== - std::string DebugString(const ASTNode* node) + std::string DebugString(const ASTNode* node, const PrintOptions& opts) { std::ostringstream oss; - DebugPrinter printer(oss); + DebugPrinter printer(oss, opts); printer.Print(node); return oss.str(); } - std::string DebugString(const ParseResult& result) + std::string DebugString(const ParseResult& result, const PrintOptions& opts) { std::ostringstream oss; - DebugPrinter printer(oss); + DebugPrinter printer(oss, opts); printer.PrintParseResult(result); return oss.str(); } - void DebugPrint(const ASTNode* node) + void DebugPrint(const ASTNode* node, const PrintOptions& opts) { - DebugPrinter printer(std::cout); + DebugPrinter printer(std::cout, opts); printer.Print(node); } - void DebugPrint(const ParseResult& result) + void DebugPrint(const ParseResult& result, const PrintOptions& opts) { - DebugPrinter printer(std::cout); + 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); } } diff --git a/lsp-server/test/test_ast/debug_printer.hpp b/lsp-server/test/test_ast/debug_printer.hpp index 3e28666..e0b0aa5 100644 --- a/lsp-server/test/test_ast/debug_printer.hpp +++ b/lsp-server/test/test_ast/debug_printer.hpp @@ -7,16 +7,88 @@ namespace lsp::language::ast { + // ===== 打印配置 ===== + struct PrintOptions + { + bool show_source_code = false; // 是否显示源代码片段 + bool show_location = true; // 是否显示位置信息 + bool use_colors = true; // 是否使用颜色 + bool use_tree_chars = true; // 是否使用树形字符 + bool compact_mode = false; // 紧凑模式 + bool show_node_kind = false; // 是否显示节点类型枚举 + int indent_size = 2; // 缩进大小 + int max_source_length = 60; // 源码最大显示长度 + + // 预设配置 + static PrintOptions Verbose() + { + PrintOptions opts; + opts.show_source_code = true; + opts.show_location = true; + opts.show_node_kind = true; + opts.compact_mode = false; + return opts; + } + + static PrintOptions Compact() + { + PrintOptions opts; + opts.compact_mode = true; + opts.use_tree_chars = false; + opts.show_location = false; + return opts; + } + + static PrintOptions Default() + { + return PrintOptions(); + } + }; + + // ===== ANSI 颜色代码 ===== + namespace Color + { + inline const char* Reset = "\033[0m"; + inline const char* Bold = "\033[1m"; + inline const char* Dim = "\033[2m"; + + // 前景色 + inline const char* Red = "\033[31m"; + inline const char* Green = "\033[32m"; + inline const char* Yellow = "\033[33m"; + inline const char* Blue = "\033[34m"; + inline const char* Magenta = "\033[35m"; + inline const char* Cyan = "\033[36m"; + inline const char* White = "\033[37m"; + inline const char* Gray = "\033[90m"; + + // 亮色 + inline const char* BrightRed = "\033[91m"; + inline const char* BrightGreen = "\033[92m"; + inline const char* BrightYellow = "\033[93m"; + inline const char* BrightBlue = "\033[94m"; + inline const char* BrightMagenta = "\033[95m"; + inline const char* BrightCyan = "\033[96m"; + } + class DebugPrinter : public ASTVisitor { public: - explicit DebugPrinter(std::ostream& os = std::cout, int indent_size = 2) : - os_(os), indent_size_(indent_size), current_indent_(0) {} + explicit DebugPrinter(std::ostream& os = std::cout, const PrintOptions& opts = PrintOptions::Default()) : + os_(os), options_(opts), current_indent_(0), source_code_(nullptr) {} void Print(const ASTNode* node); void PrintStatements(const std::vector& statements); void PrintParseResult(const ParseResult& result); + // 设置源代码用于显示 + void SetSourceCode(const std::string* source) { source_code_ = source; } + + // 设置打印选项 + void SetOptions(const PrintOptions& opts) { options_ = opts; } + + // Visitor 接口实现 + void VisitProgram(Program& node) override; void VisitUnitDefinition(UnitDefinition& node) override; void VisitClassDefinition(ClassDefinition& node) override; void VisitClassMember(ClassMember& node) override; @@ -69,20 +141,40 @@ namespace lsp::language::ast private: std::ostream& os_; - int indent_size_; + PrintOptions options_; int current_indent_; + const std::string* source_code_; + std::vector is_last_child_stack_; // 用于树形结构绘制 - void IncreaseIndent() { current_indent_ += indent_size_; } - void DecreaseIndent() { current_indent_ -= indent_size_; } - void PrintIndent(); + // 缩进控制 + void IncreaseIndent() { current_indent_ += options_.indent_size; } + void DecreaseIndent() { current_indent_ -= options_.indent_size; } + + // 输出辅助 + void PrintIndent(bool is_last = false); + void PrintTreePrefix(bool is_last = false); std::string GetIndent() const; - void PrintLocation(const Location& loc); + // 颜色辅助 + const char* GetColor(const char* color) const; + void PrintColored(const std::string& text, const char* color); + + // 节点信息输出 void PrintNodeHeader(const std::string& type_name, const Location& loc); - void PrintExpression(const Expression* expr); + void PrintLocation(const Location& loc); + void PrintSourceSnippet(const Location& loc); + void PrintKeyValue(const std::string& key, const std::string& value, const char* value_color = nullptr); + void PrintKeyValue(const std::string& key, int value); + void PrintKeyValue(const std::string& key, bool value); + + // 表达式和语句打印 + void PrintExpression(const Expression* expr, const std::string& label = "", bool is_last = false); + void PrintStatement(const Statement* stmt, const std::string& label = "", bool is_last = false); void PrintSignature(const Signature& sig); - void PrintParameter(const Parameter& param); - void PrintLeftHandSide(const LeftHandSide& lhs); + void PrintParameter(const Parameter& param, bool is_last = false); + void PrintLeftHandSide(const LeftHandSide& lhs, const std::string& label = "", bool is_last = false); + + // 枚举值打印 void PrintOperator(BinaryOperator op); void PrintOperator(UnaryOperator op); void PrintOperator(AssignmentOperator op); @@ -91,10 +183,21 @@ namespace lsp::language::ast void PrintMethodModifier(MethodModifier modifier); void PrintReferenceModifier(ReferenceModifier modifier); void PrintError(const ParseError& error); + + // 工具函数 + std::string EscapeString(const std::string& str) const; + std::string TruncateString(const std::string& str, size_t max_len) const; + std::string GetSourceText(const Location& loc) const; }; - std::string DebugString(const ASTNode* node); - std::string DebugString(const ParseResult& result); - void DebugPrint(const ASTNode* node); - void DebugPrint(const ParseResult& result); + // 便捷函数 + std::string DebugString(const ASTNode* node, const PrintOptions& opts = PrintOptions::Default()); + std::string DebugString(const ParseResult& result, const PrintOptions& opts = PrintOptions::Default()); + + void DebugPrint(const ASTNode* node, const PrintOptions& opts = PrintOptions::Default()); + void DebugPrint(const ParseResult& result, const PrintOptions& opts = PrintOptions::Default()); + + // 带源码的打印 + void DebugPrint(const ASTNode* node, const std::string& source, const PrintOptions& opts = PrintOptions::Default()); + void DebugPrint(const ParseResult& result, const std::string& source, const PrintOptions& opts = PrintOptions::Default()); } diff --git a/lsp-server/test/test_ast/test.cpp b/lsp-server/test/test_ast/test.cpp index e9ef581..b95f107 100644 --- a/lsp-server/test/test_ast/test.cpp +++ b/lsp-server/test/test_ast/test.cpp @@ -105,12 +105,23 @@ void PrintUsage(const char* program_name) { std::cout << "Usage: " << program_name << " [options]\n"; std::cout << "\nOptions:\n"; - std::cout << " -v, --verbose Print verbose output\n"; - std::cout << " -i, --incremental Test incremental parsing\n"; - std::cout << " -h, --help Show this help message\n"; - std::cout << "\nExample:\n"; + std::cout << " -v, --verbose Show verbose output with source code\n"; + std::cout << " -c, --compact Use compact output mode\n"; + std::cout << " -s, --show-source Show source code snippets (default: off)\n"; + std::cout << " -l, --hide-location Hide location information\n"; + std::cout << " -n, --no-colors Disable colored output\n"; + std::cout << " -t, --no-tree Disable tree characters\n"; + std::cout << " -k, --show-kind Show node kind enums\n"; + std::cout << " -i, --incremental Test incremental parsing\n"; + std::cout << " -h, --help Show this help message\n"; + std::cout << "\nPreset Modes:\n"; + std::cout << " --verbose Equivalent to: -s -k\n"; + std::cout << " --compact Equivalent to: -c -l -t\n"; + std::cout << "\nExamples:\n"; std::cout << " " << program_name << " test.tsf\n"; - std::cout << " " << program_name << " test.tsf -v -s\n"; + std::cout << " " << program_name << " test.tsf --verbose\n"; + std::cout << " " << program_name << " test.tsf --compact\n"; + std::cout << " " << program_name << " test.tsf -s -n # Show source without colors\n"; } int main(int argc, char* argv[]) @@ -122,9 +133,11 @@ int main(int argc, char* argv[]) } std::string filepath; - bool verbose = false; bool test_incremental = false; + // 默认打印选项 + PrintOptions opts = PrintOptions::Default(); + // 解析命令行参数 for (int i = 1; i < argc; ++i) { @@ -136,7 +149,31 @@ int main(int argc, char* argv[]) } else if (arg == "-v" || arg == "--verbose") { - verbose = true; + opts = PrintOptions::Verbose(); + } + else if (arg == "-c" || arg == "--compact") + { + opts = PrintOptions::Compact(); + } + else if (arg == "-s" || arg == "--show-source") + { + opts.show_source_code = true; + } + else if (arg == "-l" || arg == "--hide-location") + { + opts.show_location = false; + } + else if (arg == "-n" || arg == "--no-colors") + { + opts.use_colors = false; + } + else if (arg == "-t" || arg == "--no-tree") + { + opts.use_tree_chars = false; + } + else if (arg == "-k" || arg == "--show-kind") + { + opts.show_node_kind = true; } else if (arg == "-i" || arg == "--incremental") { @@ -158,71 +195,68 @@ int main(int argc, char* argv[]) // 读取文件 std::cout << "Reading file: " << filepath << "\n"; std::string source = ReadFile(filepath); - - if (verbose) - { - std::cout << "File size: " << source.length() << " bytes\n"; - std::cout << "----------------------------------------\n"; - std::cout << source << "\n"; - std::cout << "----------------------------------------\n\n"; - } + std::cout << "File size: " << source.length() << " bytes\n\n"; // 创建 Tree-Sitter 解析器 - std::cout << "Parsing with Tree-Sitter...\n"; TreeSitterParser ts_parser; TSTree* tree = ts_parser.Parse(source); TSNode root = ts_parser.GetRootNode(); - if (verbose) - { - std::cout << "Root node type: " << ts_node_type(root) << "\n"; - std::cout << "Root node child count: " << ts_node_child_count(root) << "\n\n"; - } - // 创建 AST 反序列化器 Deserializer deserializer; ParseResult result; - if (test_incremental) { - std::cout << "Using incremental parsing...\n"; + std::cout << "Using incremental parsing...\n\n"; auto inc_result = deserializer.ParseIncremental(root, source); result = std::move(inc_result.result); + std::cout << "Incremental Parse Statistics:\n"; + std::cout << " Nodes parsed: " << inc_result.nodes_parsed << "\n"; + std::cout << " Nodes unchanged: " << inc_result.nodes_unchanged << "\n"; + std::cout << " Total nodes: " << inc_result.TotalNodes() << "\n"; + std::cout << " Change rate: " << (inc_result.ChangeRate() * 100) << "%\n\n"; } else { - std::cout << "Using full parsing...\n"; result = deserializer.Parse(root, source); } - // 打印解析结果 - std::cout << "\n"; - DebugPrint(result); + // 打印 AST 结果(带源码) + DebugPrint(result, source, opts); // 打印摘要 - std::cout << "\n========================================\n"; - std::cout << "Summary:\n"; + std::cout << "\n"; + std::cout << Color::BrightBlue << "========================================\n" + << Color::Reset; + std::cout << Color::BrightCyan << "Summary:\n" + << Color::Reset; std::cout << " File: " << filepath << "\n"; std::cout << " Size: " << source.length() << " bytes\n"; - std::cout << " AST Nodes: " << result.statements.size() << "\n"; - std::cout << " Errors: " << result.errors.size() << "\n"; + if (result.root) + { + std::cout << " Statements: " << result.root->statements.size() << "\n"; + } + + std::cout << " Errors: "; if (result.HasErrors()) { - std::cout << " Status: FAILED (with errors)\n"; + std::cout << Color::BrightRed << result.errors.size() << " ✗" << Color::Reset << "\n"; + std::cout << " Status: " << Color::BrightRed << "FAILED" << Color::Reset << "\n"; return 1; } else { - std::cout << " Status: SUCCESS\n"; + std::cout << Color::BrightGreen << "0 ✓" << Color::Reset << "\n"; + std::cout << " Status: " << Color::BrightGreen << "SUCCESS" << Color::Reset << "\n"; return 0; } } catch (const std::exception& e) { - std::cerr << "Error: " << e.what() << "\n"; + std::cerr << Color::BrightRed << "Error: " << e.what() << Color::Reset << "\n"; return 1; } }