tsl-devkit/lsp-server/test/test_ast/debug_printer.cpp

2532 lines
68 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "debug_printer.hpp"
#include <sstream>
namespace lsp::language::ast
{
// ===== 辅助函数实现 =====
void DebugPrinter::Print(const ASTNode* node)
{
if (!node)
{
os_ << GetColor(Color::Gray) << "<null>" << GetColor(Color::Reset) << "\n";
return;
}
const_cast<ASTNode*>(node)->Accept(*this);
}
void DebugPrinter::PrintStatements(const std::vector<StatementPtr>& statements)
{
for (size_t i = 0; i < statements.size(); ++i)
{
bool is_last = (i == statements.size() - 1);
is_last_child_stack_.push_back(is_last);
PrintStatement(statements[i].get(), "", is_last);
is_last_child_stack_.pop_back();
}
}
void DebugPrinter::PrintParseResult(const ParseResult& result)
{
if (result.HasErrors())
{
os_ << GetColor(Color::BrightRed) << "Parse Errors:\n"
<< GetColor(Color::Reset);
for (const auto& error : result.errors)
{
PrintError(error);
}
os_ << "\n";
}
if (result.root)
{
Print(result.root.get());
}
}
// ===== 缩进和树形结构 =====
void DebugPrinter::PrintIndent(std::optional<bool> is_last)
{
if (!options_.use_tree_chars)
{
os_ << std::string(current_indent_, ' ');
return;
}
bool is_last_val = is_last.value_or(
!is_last_child_stack_.empty() ? is_last_child_stack_.back() : false);
for (size_t i = 0; i < is_last_child_stack_.size(); ++i)
{
if (i == is_last_child_stack_.size() - 1)
{
os_ << (is_last_val ? "└─ " : "├─ ");
}
else
{
os_ << (is_last_child_stack_[i] ? " " : "");
}
}
}
void DebugPrinter::PrintTreePrefix(bool is_last)
{
if (!options_.use_tree_chars)
{
os_ << std::string(current_indent_, ' ');
return;
}
for (size_t i = 0; i < is_last_child_stack_.size(); ++i)
{
os_ << (is_last_child_stack_[i] ? " " : "");
}
os_ << (is_last ? "└─ " : "├─ ");
}
std::string DebugPrinter::GetIndent() const
{
return std::string(current_indent_, ' ');
}
// ===== 颜色辅助 =====
const char* DebugPrinter::GetColor(const char* color) const
{
return options_.use_colors ? color : "";
}
void DebugPrinter::PrintColored(const std::string& text, const char* color)
{
os_ << GetColor(color) << text << GetColor(Color::Reset);
}
// ===== 节点信息输出 =====
void DebugPrinter::PrintNodeHeader(const std::string& type_name, const Location& loc)
{
PrintIndent();
PrintColored(type_name, Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(loc);
}
if (options_.show_source_code)
{
PrintSourceSnippet(loc);
}
os_ << "\n";
}
void DebugPrinter::PrintLocation(const Location& loc)
{
os_ << GetColor(Color::Gray) << "["
<< loc.start_line << ":" << loc.start_column << " - "
<< loc.end_line << ":" << loc.end_column << "]"
<< GetColor(Color::Reset);
}
void DebugPrinter::PrintSourceSnippet(const Location& loc)
{
if (!source_code_)
return;
std::string snippet = GetSourceText(loc);
if (snippet.empty())
return;
snippet = TruncateString(snippet, options_.max_source_length);
snippet = EscapeString(snippet);
os_ << "\n";
PrintTreePrefix(false);
os_ << GetColor(Color::Dim) << " Source: \"" << snippet << "\""
<< GetColor(Color::Reset);
}
void DebugPrinter::PrintKeyValue(const std::string& key, const std::string& value, const Location& location, const char* value_color)
{
PrintIndent();
PrintColored(key + ": ", Color::Yellow);
PrintColored(value, value_color ? value_color : Color::Green);
if (options_.show_location)
{
os_ << " ";
PrintLocation(location);
}
os_ << "\n";
}
void DebugPrinter::PrintKeyValue(const std::string& key, const std::string& value, const char* value_color)
{
PrintIndent();
PrintColored(key + ": ", Color::Yellow);
PrintColored(value, value_color ? value_color : Color::Green);
os_ << "\n";
}
void DebugPrinter::PrintKeyValue(const std::string& key, int value)
{
PrintIndent();
PrintColored(key + ": ", Color::Yellow);
os_ << value << "\n";
}
void DebugPrinter::PrintKeyValue(const std::string& key, bool value)
{
PrintIndent();
PrintColored(key + ": ", Color::Yellow);
PrintColored(value ? "true" : "false", value ? Color::BrightGreen : Color::BrightRed);
os_ << "\n";
}
// ===== 表达式和语句打印 =====
void DebugPrinter::PrintExpression(const Expression* expr, const std::string& label, bool is_last)
{
if (!expr)
{
PrintIndent();
if (!label.empty())
{
PrintColored(label + ": ", Color::Yellow);
}
PrintColored("<null>", Color::Gray);
os_ << "\n";
return;
}
if (!label.empty())
{
PrintIndent();
PrintColored(label + ":", Color::Yellow);
os_ << "\n";
IncreaseIndent();
}
is_last_child_stack_.push_back(is_last);
const_cast<Expression*>(expr)->Accept(*this);
is_last_child_stack_.pop_back();
if (!label.empty())
{
DecreaseIndent();
}
}
void DebugPrinter::PrintStatement(const Statement* stmt, const std::string& label, bool is_last)
{
if (!stmt)
{
PrintIndent();
if (!label.empty())
{
PrintColored(label + ": ", Color::Yellow);
}
PrintColored("<null>", Color::Gray);
os_ << "\n";
return;
}
if (!label.empty())
{
PrintIndent();
PrintColored(label + ":", Color::Yellow);
os_ << "\n";
IncreaseIndent();
}
is_last_child_stack_.push_back(is_last);
const_cast<Statement*>(stmt)->Accept(*this);
is_last_child_stack_.pop_back();
if (!label.empty())
{
DecreaseIndent();
}
}
void DebugPrinter::PrintParameter(const Parameter& param, bool is_last)
{
PrintIndent(is_last);
PrintColored("Parameter: ", Color::Cyan);
PrintColored("\"" + param.name + "\"", Color::Green);
if (param.type)
{
os_ << " : ";
PrintColored(param.type->name, Color::BrightYellow);
}
if (param.is_var)
{
os_ << " " << GetColor(Color::Magenta) << "(var)" << GetColor(Color::Reset);
}
if (param.is_out)
{
os_ << " " << GetColor(Color::Magenta) << "(out)" << GetColor(Color::Reset);
}
if (param.default_value)
{
os_ << " = <expr>";
}
os_ << "\n";
}
void DebugPrinter::PrintLeftHandSide(const LValue& lhs, const std::string& label, bool is_last)
{
std::visit([&](auto&& value) {
using T = std::decay_t<decltype(value)>;
if constexpr (std::is_same_v<T, std::monostate>)
{
PrintIndent();
if (!label.empty())
{
PrintColored(label + ": ", Color::Yellow);
}
PrintColored("<empty>", Color::Gray);
os_ << "\n";
}
else if constexpr (std::is_same_v<T, ExpressionPtr>)
{
PrintExpression(value.get(), label, is_last);
}
else if constexpr (std::is_same_v<T, std::unique_ptr<Identifier>> ||
std::is_same_v<T, std::unique_ptr<AttributeExpression>> ||
std::is_same_v<T, std::unique_ptr<SubscriptExpression>> ||
std::is_same_v<T, std::unique_ptr<ColumnReference>>)
{
if (!label.empty())
{
PrintIndent();
PrintColored(label + ":", Color::Yellow);
os_ << "\n";
IncreaseIndent();
}
is_last_child_stack_.push_back(is_last);
if (value)
value->Accept(*this);
is_last_child_stack_.pop_back();
if (!label.empty())
{
DecreaseIndent();
}
}
else if constexpr (std::is_same_v<T, std::unique_ptr<UnpackPattern>>)
{
if (!label.empty())
{
PrintIndent();
PrintColored(label + ":", Color::Yellow);
os_ << "\n";
IncreaseIndent();
}
is_last_child_stack_.push_back(is_last);
if (value)
value->Accept(*this);
is_last_child_stack_.pop_back();
if (!label.empty())
{
DecreaseIndent();
}
}
},
lhs);
}
// ===== 枚举值打印 =====
void DebugPrinter::PrintOperator(BinaryOperator op)
{
PrintColored(GetBinaryOperatorSymbol(op), Color::BrightMagenta);
}
void DebugPrinter::PrintOperator(AssignmentOperator op)
{
PrintColored(GetAssignmentOperatorSymbol(op), Color::BrightMagenta);
}
void DebugPrinter::PrintLiteralKind(LiteralKind kind)
{
const char* kind_str = "";
switch (kind)
{
case LiteralKind::kNumber:
kind_str = "Number";
break;
case LiteralKind::kString:
kind_str = "String";
break;
case LiteralKind::kChar:
kind_str = "Char";
break;
case LiteralKind::kBoolean:
kind_str = "Boolean";
break;
case LiteralKind::kNil:
kind_str = "Nil";
break;
case LiteralKind::kNan:
kind_str = "NaN";
break;
case LiteralKind::kInfinity:
kind_str = "Infinity";
break;
}
PrintColored(kind_str, Color::BrightYellow);
}
void DebugPrinter::PrintAccessModifier(AccessModifier modifier)
{
const char* mod_str = "";
switch (modifier)
{
case AccessModifier::kPublic:
mod_str = "public";
break;
case AccessModifier::kProtected:
mod_str = "protected";
break;
case AccessModifier::kPrivate:
mod_str = "private";
break;
}
PrintColored(mod_str, Color::BrightYellow);
}
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::BrightYellow);
}
void DebugPrinter::PrintMethodType(MethodType type)
{
const char* type_str = "";
switch (type)
{
case MethodType::kNormal:
type_str = "normal";
break;
case MethodType::kConstructor:
type_str = "constructor";
break;
case MethodType::kDestructor:
type_str = "destructor";
break;
case MethodType::kOperatorOverload:
type_str = "operator";
break;
}
PrintColored(type_str, Color::BrightYellow);
}
void DebugPrinter::PrintReferenceModifier(ReferenceModifier modifier)
{
const char* mod_str = "";
switch (modifier)
{
case ReferenceModifier::kNone:
return;
case ReferenceModifier::kWeakRef:
mod_str = "weakref";
break;
case ReferenceModifier::kAutoRef:
mod_str = "autoref";
break;
}
PrintColored(mod_str, Color::Magenta);
}
void DebugPrinter::PrintConditionalCompilationType(ConditionalCompilationType type)
{
const char* type_str = "";
switch (type)
{
case ConditionalCompilationType::kIfDef:
type_str = "ifdef";
break;
case ConditionalCompilationType::kIfNDef:
type_str = "ifndef";
break;
case ConditionalCompilationType::kDefine:
type_str = "define";
break;
case ConditionalCompilationType::kUndef:
type_str = "undef";
break;
}
PrintColored(type_str, Color::BrightYellow);
}
void DebugPrinter::PrintTSSQLExpressionType(TSSQLExpressionType type)
{
const char* type_str = "";
switch (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;
}
PrintColored(type_str, Color::BrightYellow);
}
void DebugPrinter::PrintError(const ParseError& error)
{
os_ << GetColor(Color::BrightRed) << " Error: " << GetColor(Color::Reset)
<< error.message << "\n";
os_ << GetColor(Color::Gray) << " Location: ["
<< error.location.start_line << ":" << error.location.start_column << " - "
<< error.location.end_line << ":" << error.location.end_column << "]"
<< GetColor(Color::Reset) << "\n";
}
// ===== 工具函数 =====
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:
result += c;
break;
}
}
return result;
}
std::string DebugPrinter::TruncateString(const std::string& str, size_t max_len) const
{
if (str.length() <= max_len)
return str;
return str.substr(0, max_len - 3) + "...";
}
std::string DebugPrinter::GetSourceText(const Location& loc) const
{
if (!source_code_)
return "";
if (loc.start_byte >= source_code_->length())
return "";
size_t length = loc.end_byte - loc.start_byte;
if (loc.start_byte + length > source_code_->length())
{
length = source_code_->length() - loc.start_byte;
}
return source_code_->substr(loc.start_byte, length);
}
std::string DebugPrinter::GetNodeKindName(NodeKind kind) const
{
switch (kind)
{
case NodeKind::kIdentifier:
return "kIdentifier";
case NodeKind::kLiteral:
return "kLiteral";
case NodeKind::kArrayExpression:
return "kArrayExpression";
case NodeKind::kParenthesizedExpression:
return "kParenthesizedExpression";
case NodeKind::kAttributeExpression:
return "kAttributeExpression";
case NodeKind::kSubscriptExpression:
return "kSubscriptExpression";
case NodeKind::kCallExpression:
return "kCallExpression";
case NodeKind::kUnaryPlusExpression:
return "kUnaryPlusExpression";
case NodeKind::kUnaryMinusExpression:
return "kUnaryMinusExpression";
case NodeKind::kPrefixIncrementExpression:
return "kPrefixIncrementExpression";
case NodeKind::kPrefixDecrementExpression:
return "kPrefixDecrementExpression";
case NodeKind::kPostfixIncrementExpression:
return "kPostfixIncrementExpression";
case NodeKind::kPostfixDecrementExpression:
return "kPostfixDecrementExpression";
case NodeKind::kLogicalNotExpression:
return "kLogicalNotExpression";
case NodeKind::kBitwiseNotExpression:
return "kBitwiseNotExpression";
case NodeKind::kDerivativeExpression:
return "kDerivativeExpression";
case NodeKind::kFunctionPointerExpression:
return "kFunctionPointerExpression";
case NodeKind::kMatrixTransposeExpression:
return "kMatrixTransposeExpression";
case NodeKind::kExprOperatorExpression:
return "kExprOperatorExpression";
case NodeKind::kBinaryExpression:
return "kBinaryExpression";
case NodeKind::kTernaryExpression:
return "kTernaryExpression";
case NodeKind::kAssignmentExpression:
return "kAssignmentExpression";
case NodeKind::kAnonymousFunctionExpression:
return "kAnonymousFunctionExpression";
case NodeKind::kNewExpression:
return "kNewExpression";
case NodeKind::kEchoExpression:
return "kEchoExpression";
case NodeKind::kRaiseExpression:
return "kRaiseExpression";
case NodeKind::kInheritedExpression:
return "kInheritedExpression";
case NodeKind::kTSSQLExpression:
return "kTSSQLExpression";
case NodeKind::kColumnReference:
return "kColumnReference";
case NodeKind::kUnpackPattern:
return "kUnpackPattern";
case NodeKind::kParameter:
return "kParameter";
case NodeKind::kVarDeclaration:
return "kVarDeclaration";
case NodeKind::kStaticDeclaration:
return "kStaticDeclaration";
case NodeKind::kGlobalDeclaration:
return "kGlobalDeclaration";
case NodeKind::kConstDeclaration:
return "kConstDeclaration";
case NodeKind::kFieldDeclaration:
return "kFieldDeclaration";
case NodeKind::kExpressionStatement:
return "kExpressionStatement";
case NodeKind::kBlockStatement:
return "kBlockStatement";
case NodeKind::kIfStatement:
return "kIfStatement";
case NodeKind::kForInStatement:
return "kForInStatement";
case NodeKind::kForToStatement:
return "kForToStatement";
case NodeKind::kWhileStatement:
return "kWhileStatement";
case NodeKind::kRepeatStatement:
return "kRepeatStatement";
case NodeKind::kCaseStatement:
return "kCaseStatement";
case NodeKind::kTryStatement:
return "kTryStatement";
case NodeKind::kBreakStatement:
return "kBreakStatement";
case NodeKind::kContinueStatement:
return "kContinueStatement";
case NodeKind::kReturnStatement:
return "kReturnStatement";
case NodeKind::kUsesStatement:
return "kUsesStatement";
case NodeKind::kFunctionDeclaration:
return "kFunctionDeclaration";
case NodeKind::kFunctionDefinition:
return "kFunctionDefinition";
case NodeKind::kMethodDeclaration:
return "kMethodDeclaration";
case NodeKind::kPropertyDeclaration:
return "kPropertyDeclaration";
case NodeKind::kClassMember:
return "kClassMember";
case NodeKind::kClassDefinition:
return "kClassDefinition";
case NodeKind::kExternalMethodDefinition:
return "kExternalMethodDefinition";
case NodeKind::kUnitDefinition:
return "kUnitDefinition";
case NodeKind::kMatrixIterationStatement:
return "kMatrixIterationStatement";
case NodeKind::kCompilerDirective:
return "kCompilerDirective";
case NodeKind::kConditionalBlock:
return "kConditionalBlock";
case NodeKind::kConditionalDirective:
return "kConditionalDirective";
case NodeKind::kTSLXBlock:
return "kTSLXBlock";
case NodeKind::kProgram:
return "kProgram";
default:
return "kUnknown";
}
}
// ===== Visitor 实现 - 基础节点 =====
void DebugPrinter::VisitProgram(Program& node)
{
PrintNodeHeader("Program", node.span);
if (options_.show_node_kind)
{
IncreaseIndent();
PrintKeyValue("Kind", GetNodeKindName(node.kind));
DecreaseIndent();
}
IncreaseIndent();
PrintStatements(node.statements);
DecreaseIndent();
}
void DebugPrinter::VisitUnitDefinition(UnitDefinition& node)
{
PrintIndent();
PrintColored("UnitDefinition: ", Color::BrightCyan);
PrintColored("\"" + node.name + "\"", Color::Green);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.location);
}
os_ << "\n";
IncreaseIndent();
if (!node.interface_statements.empty())
{
PrintIndent();
PrintColored("Interface:", Color::Yellow);
os_ << "\n";
IncreaseIndent();
PrintStatements(node.interface_statements);
DecreaseIndent();
}
if (!node.implementation_statements.empty())
{
PrintIndent();
PrintColored("Implementation:", Color::Yellow);
os_ << "\n";
IncreaseIndent();
PrintStatements(node.implementation_statements);
DecreaseIndent();
}
if (!node.initialization_statements.empty())
{
PrintIndent();
PrintColored("Initialization:", Color::Yellow);
os_ << "\n";
IncreaseIndent();
PrintStatements(node.initialization_statements);
DecreaseIndent();
}
if (!node.finalization_statements.empty())
{
PrintIndent();
PrintColored("Finalization:", Color::Yellow);
os_ << "\n";
IncreaseIndent();
PrintStatements(node.finalization_statements);
DecreaseIndent();
}
DecreaseIndent();
}
void DebugPrinter::VisitClassDefinition(ClassDefinition& node)
{
PrintIndent();
PrintColored("ClassDefinition: ", Color::BrightCyan);
PrintColored("\"" + node.name + "\"", Color::Green);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.location);
}
os_ << "\n";
IncreaseIndent();
if (!node.parent_classes.empty())
{
PrintIndent();
PrintColored("Parents:", Color::Yellow);
os_ << "\n";
IncreaseIndent();
for (const auto& parent : node.parent_classes)
{
PrintIndent();
// 如果有qualifier先显示
if (parent.qualifier)
{
PrintColored(*parent.qualifier + ".", Color::Magenta);
}
PrintColored(parent.name, Color::Green);
os_ << "\n";
}
DecreaseIndent();
}
if (node.uses)
{
is_last_child_stack_.push_back(false);
node.uses->Accept(*this);
is_last_child_stack_.pop_back();
}
if (!node.members.empty())
{
PrintIndent();
PrintColored("Members:", Color::Yellow);
os_ << "\n";
IncreaseIndent();
for (size_t i = 0; i < node.members.size(); ++i)
{
is_last_child_stack_.push_back(i == node.members.size() - 1);
if (node.members[i])
node.members[i]->Accept(*this);
is_last_child_stack_.pop_back();
}
DecreaseIndent();
}
DecreaseIndent();
}
void DebugPrinter::VisitClassMember(ClassMember& node)
{
PrintIndent();
PrintColored("ClassMember", Color::BrightCyan);
if (node.access_modifier != AccessModifier::kPublic)
{
os_ << " (";
PrintAccessModifier(node.access_modifier);
os_ << ")";
}
os_ << "\n";
IncreaseIndent();
// 处理 member variant
std::visit([this](auto&& member_ptr) {
if (member_ptr)
{
is_last_child_stack_.push_back(true);
member_ptr->Accept(*this);
is_last_child_stack_.pop_back();
}
},
node.member);
DecreaseIndent();
}
void DebugPrinter::VisitMethodDeclaration(MethodDeclaration& node)
{
PrintIndent();
PrintColored("MethodDeclaration: ", Color::BrightCyan);
PrintColored("\"" + node.name + "\"", Color::Green);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.location);
}
os_ << "\n";
IncreaseIndent();
if (node.modifier != MethodModifier::kNone)
{
PrintIndent();
PrintColored("Modifier: ", Color::Yellow);
PrintMethodModifier(node.modifier);
os_ << "\n";
}
if (node.method_type != MethodType::kNormal)
{
PrintIndent();
PrintColored("Type: ", Color::Yellow);
PrintMethodType(node.method_type);
os_ << "\n";
}
if (node.is_class_method)
{
PrintKeyValue("ClassMethod", true);
}
if (!node.parameters.empty())
{
PrintIndent();
PrintColored("Parameters:", Color::Yellow);
os_ << "\n";
IncreaseIndent();
for (size_t i = 0; i < node.parameters.size(); ++i)
{
if (node.parameters[i])
{
PrintParameter(*node.parameters[i], i == node.parameters.size() - 1);
}
}
DecreaseIndent();
}
if (node.return_type)
{
PrintKeyValue("ReturnType", node.return_type->name);
}
if (node.body)
{
is_last_child_stack_.push_back(true);
PrintStatement(node.body.get(), "Body", true);
is_last_child_stack_.pop_back();
}
DecreaseIndent();
}
void DebugPrinter::VisitPropertyDeclaration(PropertyDeclaration& node)
{
PrintIndent();
PrintColored("PropertyDeclaration: ", Color::BrightCyan);
PrintColored("\"" + node.name + "\"", Color::Green);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.location);
}
os_ << "\n";
IncreaseIndent();
if (node.type)
{
PrintKeyValue("Type", node.type->name);
}
if (node.index)
{
PrintExpression(node.index.value().get(), "Index", false);
}
if (node.read_accessor)
{
PrintIndent();
PrintColored("Read: ", Color::Yellow);
PrintColored("\"" + node.read_accessor.value() + "\"", Color::Green);
if (options_.show_location && node.read_location)
{
os_ << " ";
PrintLocation(node.read_location.value());
}
os_ << "\n";
}
if (node.write_accessor)
{
PrintIndent();
PrintColored("Write: ", Color::Yellow);
PrintColored("\"" + node.write_accessor.value() + "\"", Color::Green);
if (options_.show_location && node.write_location)
{
os_ << " ";
PrintLocation(node.write_location.value());
}
os_ << "\n";
}
DecreaseIndent();
}
void DebugPrinter::VisitExternalMethodDefinition(ExternalMethodDefinition& node)
{
PrintIndent();
PrintColored("ExternalMethodDefinition: ", Color::BrightCyan);
PrintColored(node.owner_class.name + "::" + node.name, Color::Green);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.location);
}
os_ << "\n";
IncreaseIndent();
if (node.modifier != MethodModifier::kNone)
{
PrintIndent();
PrintColored("Modifier: ", Color::Yellow);
PrintMethodModifier(node.modifier);
os_ << "\n";
}
if (node.method_type != MethodType::kNormal)
{
PrintIndent();
PrintColored("Type: ", Color::Yellow);
PrintMethodType(node.method_type);
os_ << "\n";
}
if (!node.parameters.empty())
{
PrintIndent();
PrintColored("Parameters:", Color::Yellow);
os_ << "\n";
IncreaseIndent();
for (size_t i = 0; i < node.parameters.size(); ++i)
{
if (node.parameters[i])
{
PrintParameter(*node.parameters[i], i == node.parameters.size() - 1);
}
}
DecreaseIndent();
}
if (node.return_type)
{
PrintKeyValue("ReturnType", node.return_type->name);
}
if (node.body)
{
PrintStatement(node.body.get(), "Body", true);
}
DecreaseIndent();
}
// ===== 基础表达式 =====
void DebugPrinter::VisitIdentifier(Identifier& node)
{
PrintIndent();
PrintColored("Identifier: ", Color::BrightCyan);
PrintColored("\"" + node.name + "\"", Color::Green);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.location);
}
os_ << "\n";
}
void DebugPrinter::VisitLiteral(Literal& node)
{
PrintIndent();
PrintColored("Literal: ", Color::BrightCyan);
PrintColored("\"" + node.name + "\"", Color::Green);
os_ << " (";
PrintLiteralKind(node.literal_kind);
os_ << ")";
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.location);
}
os_ << "\n";
}
void DebugPrinter::VisitArrayExpression(ArrayExpression& node)
{
PrintIndent();
PrintColored("ArrayExpression", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
if (!node.elements.empty())
{
IncreaseIndent();
for (size_t i = 0; i < node.elements.size(); ++i)
{
const auto& elem = node.elements[i];
bool is_last = (i == node.elements.size() - 1);
if (elem.key)
{
PrintIndent();
PrintColored("Element:", Color::Yellow);
os_ << "\n";
IncreaseIndent();
PrintExpression(elem.key->get(), "Key", false);
PrintExpression(elem.value.get(), "Value", true);
DecreaseIndent();
}
else
{
PrintExpression(elem.value.get(), "", is_last);
}
}
DecreaseIndent();
}
}
void DebugPrinter::VisitParenthesizedExpression(ParenthesizedExpression& node)
{
PrintIndent();
PrintColored("ParenthesizedExpression", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
for (size_t i = 0; i < node.elements.size(); ++i)
{
const auto& elem = node.elements[i];
bool is_last = (i == node.elements.size() - 1);
if (elem.key.has_value())
{
PrintIndent();
PrintColored("Element (key-value):", Color::Yellow);
os_ << "\n";
IncreaseIndent();
PrintExpression(elem.key.value().get(), "Key", false);
PrintExpression(elem.value.get(), "Value", is_last);
DecreaseIndent();
}
else
{
PrintExpression(elem.value.get(), "", is_last);
}
}
DecreaseIndent();
}
// ===== 访问表达式 =====
void DebugPrinter::VisitCallExpression(CallExpression& node)
{
PrintIndent();
PrintColored("CallExpression", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintExpression(node.function.get(), "Function", node.arguments.empty());
if (!node.arguments.empty())
{
PrintIndent();
PrintColored("Arguments:", Color::Yellow);
os_ << "\n";
IncreaseIndent();
for (size_t i = 0; i < node.arguments.size(); ++i)
{
bool is_last = (i == node.arguments.size() - 1);
const auto& arg = node.arguments[i];
std::string label = "Argument";
if (arg.name)
{
label += " (" + arg.name.value() + ")";
}
if (arg.is_const)
{
label += " [const]";
}
is_last_child_stack_.push_back(is_last);
PrintExpression(arg.value.get(), label, is_last);
is_last_child_stack_.pop_back();
}
DecreaseIndent();
}
DecreaseIndent();
}
void DebugPrinter::VisitAttributeExpression(AttributeExpression& node)
{
PrintIndent();
PrintColored("AttributeExpression", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintExpression(node.object.get(), "Object", false);
PrintExpression(node.attribute.get(), "Attribute", true);
DecreaseIndent();
}
void DebugPrinter::VisitSubscriptExpression(SubscriptExpression& node)
{
PrintIndent();
PrintColored("SubscriptExpression", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintExpression(node.base.get(), "Base", node.indices.empty());
if (!node.indices.empty())
{
PrintIndent();
PrintColored("Indices:", Color::Yellow);
os_ << "\n";
IncreaseIndent();
for (size_t i = 0; i < node.indices.size(); ++i)
{
bool is_last = (i == node.indices.size() - 1);
const auto& idx = node.indices[i];
PrintIndent();
PrintColored("Index " + std::to_string(i), Color::Yellow);
if (idx.is_slice)
{
PrintColored(" (slice)", Color::Gray);
}
if (idx.is_empty_slice)
{
PrintColored(" (empty)", Color::Gray);
}
os_ << "\n";
IncreaseIndent();
if (idx.start)
{
is_last_child_stack_.push_back(false);
PrintExpression(idx.start.get(), "Start", !idx.end && !idx.step);
is_last_child_stack_.pop_back();
}
if (idx.end)
{
is_last_child_stack_.push_back(false);
PrintExpression(idx.end.get(), "End", !idx.step);
is_last_child_stack_.pop_back();
}
if (idx.step)
{
is_last_child_stack_.push_back(is_last);
PrintExpression(idx.step.get(), "Step", true);
is_last_child_stack_.pop_back();
}
DecreaseIndent();
}
DecreaseIndent();
}
DecreaseIndent();
}
// ===== 一元表达式 =====
void DebugPrinter::VisitUnaryPlusExpression(UnaryPlusExpression& node)
{
PrintIndent();
PrintColored("UnaryPlusExpression", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintExpression(node.argument.get(), "Operand", true);
DecreaseIndent();
}
void DebugPrinter::VisitUnaryMinusExpression(UnaryMinusExpression& node)
{
PrintIndent();
PrintColored("UnaryMinusExpression", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintExpression(node.argument.get(), "Operand", true);
DecreaseIndent();
}
void DebugPrinter::VisitPrefixIncrementExpression(PrefixIncrementExpression& node)
{
PrintIndent();
PrintColored("PrefixIncrementExpression", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintExpression(node.argument.get(), "Operand", true);
DecreaseIndent();
}
void DebugPrinter::VisitPrefixDecrementExpression(PrefixDecrementExpression& node)
{
PrintIndent();
PrintColored("PrefixDecrementExpression", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintExpression(node.argument.get(), "Operand", true);
DecreaseIndent();
}
void DebugPrinter::VisitPostfixIncrementExpression(PostfixIncrementExpression& node)
{
PrintIndent();
PrintColored("PostfixIncrementExpression", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintExpression(node.argument.get(), "Operand", true);
DecreaseIndent();
}
void DebugPrinter::VisitPostfixDecrementExpression(PostfixDecrementExpression& node)
{
PrintIndent();
PrintColored("PostfixDecrementExpression", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintExpression(node.argument.get(), "Operand", true);
DecreaseIndent();
}
void DebugPrinter::VisitLogicalNotExpression(LogicalNotExpression& node)
{
PrintIndent();
PrintColored("LogicalNotExpression", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintExpression(node.argument.get(), "Operand", true);
DecreaseIndent();
}
void DebugPrinter::VisitBitwiseNotExpression(BitwiseNotExpression& node)
{
PrintIndent();
PrintColored("BitwiseNotExpression", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintExpression(node.argument.get(), "Operand", true);
DecreaseIndent();
}
void DebugPrinter::VisitDerivativeExpression(DerivativeExpression& node)
{
PrintIndent();
PrintColored("DerivativeExpression", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintExpression(node.argument.get(), "Operand", true);
DecreaseIndent();
}
void DebugPrinter::VisitFunctionPointerExpression(FunctionPointerExpression& node)
{
PrintIndent();
PrintColored("FunctionPointerExpression", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintExpression(node.argument.get(), "Argument", true);
DecreaseIndent();
}
void DebugPrinter::VisitMatrixTransposeExpression(MatrixTransposeExpression& node)
{
PrintIndent();
PrintColored("MatrixTransposeExpression", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintExpression(node.argument.get(), "Operand", true);
DecreaseIndent();
}
void DebugPrinter::VisitExprOperatorExpression(ExprOperatorExpression& node)
{
PrintIndent();
PrintColored("ExprOperatorExpression", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintExpression(node.argument.get(), "Operand", true);
DecreaseIndent();
}
// ===== 二元和三元表达式 =====
void DebugPrinter::VisitBinaryExpression(BinaryExpression& node)
{
PrintIndent();
PrintColored("BinaryExpression: ", Color::BrightCyan);
PrintOperator(node.op);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintExpression(node.left.get(), "Left", false);
PrintExpression(node.right.get(), "Right", true);
DecreaseIndent();
}
void DebugPrinter::VisitTernaryExpression(TernaryExpression& node)
{
PrintIndent();
PrintColored("TernaryExpression", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintExpression(node.condition.get(), "Condition", false);
PrintExpression(node.consequence.get(), "Consequence", false);
PrintExpression(node.alternative.get(), "Alternative", true);
DecreaseIndent();
}
void DebugPrinter::VisitAssignmentExpression(AssignmentExpression& node)
{
PrintIndent();
PrintColored("AssignmentExpression: ", Color::BrightCyan);
PrintOperator(node.op);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintLeftHandSide(node.left, "Left", false);
PrintExpression(node.right.get(), "Right", true);
DecreaseIndent();
}
// ===== 特殊表达式 =====
void DebugPrinter::VisitAnonymousFunctionExpression(AnonymousFunctionExpression& node)
{
PrintIndent();
PrintColored("AnonymousFunctionExpression", Color::BrightCyan);
if (node.is_static)
{
os_ << " " << GetColor(Color::Magenta) << "(static)" << GetColor(Color::Reset);
}
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
if (!node.parameters.empty())
{
PrintIndent();
PrintColored("Parameters:", Color::Yellow);
os_ << "\n";
IncreaseIndent();
for (size_t i = 0; i < node.parameters.size(); ++i)
{
if (node.parameters[i])
{
PrintParameter(*node.parameters[i], i == node.parameters.size() - 1);
}
}
DecreaseIndent();
}
if (node.return_type)
{
PrintKeyValue("ReturnType", node.return_type->name);
}
if (node.body)
{
PrintStatement(node.body.get(), "Body", true);
}
DecreaseIndent();
}
void DebugPrinter::VisitNewExpression(NewExpression& node)
{
PrintIndent();
PrintColored("NewExpression", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
if (node.class_expr)
{
IncreaseIndent();
PrintExpression(node.class_expr.get(), "Class", true);
DecreaseIndent();
}
}
void DebugPrinter::VisitEchoExpression(EchoExpression& node)
{
PrintIndent();
PrintColored("EchoExpression", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
if (!node.expressions.empty())
{
IncreaseIndent();
for (size_t i = 0; i < node.expressions.size(); ++i)
{
PrintExpression(node.expressions[i].get(), "", i == node.expressions.size() - 1);
}
DecreaseIndent();
}
}
void DebugPrinter::VisitRaiseExpression(RaiseExpression& node)
{
PrintIndent();
PrintColored("RaiseExpression", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintExpression(node.exception.get(), "Exception", true);
DecreaseIndent();
}
void DebugPrinter::VisitInheritedExpression(InheritedExpression& node)
{
PrintIndent();
PrintColored("InheritedExpression", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
if (node.call)
{
IncreaseIndent();
PrintExpression(node.call.get(), "Call", true);
DecreaseIndent();
}
}
void DebugPrinter::VisitTSSQLExpression(TSSQLExpression& node)
{
PrintIndent();
PrintColored("TSSQLExpression: ", Color::BrightCyan);
PrintTSSQLExpressionType(node.sql_type);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintIndent();
PrintColored("SQL: ", Color::Yellow);
PrintColored("\"" + EscapeString(TruncateString(node.raw_sql, 100)) + "\"", Color::Green);
os_ << "\n";
if (options_.show_location)
{
PrintIndent();
PrintColored("SQL Location: ", Color::Yellow);
PrintLocation(node.sql_location);
os_ << "\n";
}
DecreaseIndent();
}
void DebugPrinter::VisitColumnReference(ColumnReference& node)
{
PrintIndent();
PrintColored("ColumnReference", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
if (node.value)
{
IncreaseIndent();
PrintExpression(node.value.get(), "Value", true);
DecreaseIndent();
}
}
// ===== 模式 =====
void DebugPrinter::VisitParameter(Parameter& node)
{
PrintIndent();
PrintColored("Parameter: ", Color::Cyan);
PrintColored("\"" + node.name + "\"", Color::Green);
if (node.type)
{
os_ << " : ";
PrintColored(node.type->name, Color::BrightYellow);
}
if (node.is_var)
{
os_ << " " << GetColor(Color::Magenta) << "(var)" << GetColor(Color::Reset);
}
if (node.is_out)
{
os_ << " " << GetColor(Color::Magenta) << "(out)" << GetColor(Color::Reset);
}
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.location);
}
os_ << "\n";
if (node.default_value)
{
IncreaseIndent();
PrintExpression(node.default_value.get(), "DefaultValue", true);
DecreaseIndent();
}
}
void DebugPrinter::VisitUnpackPattern(UnpackPattern& node)
{
PrintIndent();
PrintColored("UnpackPattern", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
if (!node.elements.empty())
{
IncreaseIndent();
for (size_t i = 0; i < node.elements.size(); ++i)
{
bool is_last = (i == node.elements.size() - 1);
PrintLeftHandSide(node.elements[i], "Element", is_last);
}
DecreaseIndent();
}
}
// ===== 语句 =====
void DebugPrinter::VisitExpressionStatement(ExpressionStatement& node)
{
PrintIndent();
PrintColored("ExpressionStatement", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintExpression(node.expression.get(), "", true);
DecreaseIndent();
}
void DebugPrinter::VisitBlockStatement(BlockStatement& node)
{
PrintIndent();
PrintColored("BlockStatement", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintStatements(node.statements);
DecreaseIndent();
}
void DebugPrinter::VisitIfStatement(IfStatement& node)
{
PrintIndent();
PrintColored("IfStatement", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
// Print all if/elseif branches
for (size_t i = 0; i < node.branches.size(); ++i)
{
const auto& branch = node.branches[i];
bool is_last_branch = (i == node.branches.size() - 1) && !node.else_body;
PrintIndent();
PrintColored(i == 0 ? "If Branch:" : "ElseIf Branch:", Color::Yellow);
os_ << "\n";
IncreaseIndent();
PrintExpression(branch.condition.get(), "Condition", false);
PrintStatement(branch.body.get(), "Body", is_last_branch);
DecreaseIndent();
}
// Print else branch if exists
if (node.else_body)
{
PrintIndent();
PrintColored("Else Branch:", Color::Yellow);
os_ << "\n";
IncreaseIndent();
PrintStatement(node.else_body.get(), "Body", true);
DecreaseIndent();
}
DecreaseIndent();
}
void DebugPrinter::VisitForInStatement(ForInStatement& node)
{
PrintIndent();
PrintColored("ForInStatement", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintKeyValue("Key", node.key);
PrintKeyValue("Value", node.value);
PrintExpression(node.collection.get(), "Collection", false);
PrintStatement(node.body.get(), "Body", true);
DecreaseIndent();
}
void DebugPrinter::VisitForToStatement(ForToStatement& node)
{
PrintIndent();
PrintColored("ForToStatement", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintKeyValue("Counter", node.counter);
PrintKeyValue("IsDownto", node.is_downto);
PrintExpression(node.start.get(), "Start", false);
PrintExpression(node.end.get(), "End", !node.step && !node.body);
if (node.step)
{
PrintExpression(node.step.get(), "Step", !node.body);
}
if (node.body)
{
PrintStatement(node.body.get(), "Body", true);
}
DecreaseIndent();
}
void DebugPrinter::VisitWhileStatement(WhileStatement& node)
{
PrintIndent();
PrintColored("WhileStatement", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintExpression(node.condition.get(), "Condition", false);
PrintStatement(node.body.get(), "Body", true);
DecreaseIndent();
}
void DebugPrinter::VisitRepeatStatement(RepeatStatement& node)
{
PrintIndent();
PrintColored("RepeatStatement", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
// Print body statements
PrintIndent();
PrintColored("Body:", Color::Yellow);
os_ << "\n";
IncreaseIndent();
for (size_t i = 0; i < node.body.size(); ++i)
{
PrintStatement(node.body[i].get(), "", i == node.body.size() - 1);
}
DecreaseIndent();
PrintExpression(node.condition.get(), "Condition", true);
DecreaseIndent();
}
void DebugPrinter::VisitCaseStatement(CaseStatement& node)
{
PrintIndent();
PrintColored("CaseStatement", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintExpression(node.discriminant.get(), "Discriminant", false);
for (size_t i = 0; i < node.branches.size(); ++i)
{
const auto& branch = node.branches[i];
bool is_last_branch = (i == node.branches.size() - 1) && !node.else_body;
PrintIndent();
PrintColored("Branch:", Color::Yellow);
os_ << "\n";
IncreaseIndent();
PrintIndent();
PrintColored("Values:", Color::Yellow);
os_ << "\n";
IncreaseIndent();
for (size_t j = 0; j < branch.values.size(); ++j)
{
PrintExpression(branch.values[j].get(), "", j == branch.values.size() - 1);
}
DecreaseIndent();
if (branch.body)
{
is_last_child_stack_.push_back(is_last_branch);
PrintStatement(branch.body.get(), "Body", is_last_branch);
is_last_child_stack_.pop_back();
}
DecreaseIndent();
}
if (node.else_body)
{
PrintStatement(node.else_body.get(), "Else", true);
}
DecreaseIndent();
}
void DebugPrinter::VisitTryStatement(TryStatement& node)
{
PrintIndent();
PrintColored("TryStatement", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
if (node.try_body)
{
PrintStatement(node.try_body.get(), "Try", !node.except_body);
}
if (node.except_body)
{
PrintStatement(node.except_body.get(), "Except", true);
}
DecreaseIndent();
}
void DebugPrinter::VisitBreakStatement(BreakStatement& node)
{
PrintIndent();
PrintColored("BreakStatement", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
}
void DebugPrinter::VisitContinueStatement(ContinueStatement& node)
{
PrintIndent();
PrintColored("ContinueStatement", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
}
void DebugPrinter::VisitReturnStatement(ReturnStatement& node)
{
PrintIndent();
PrintColored("ReturnStatement", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
if (node.value)
{
IncreaseIndent();
PrintExpression(node.value.get(), "", true);
DecreaseIndent();
}
}
void DebugPrinter::VisitUsesStatement(UsesStatement& node)
{
PrintIndent();
PrintColored("UsesStatement", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
for (size_t i = 0; i < node.units.size(); ++i)
{
PrintIndent(i == node.units.size() - 1);
PrintColored("\"" + node.units[i].name + "\"", Color::Green);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.units[i].location);
}
os_ << "\n";
}
DecreaseIndent();
}
void DebugPrinter::VisitMatrixIterationStatement(MatrixIterationStatement& node)
{
PrintIndent();
PrintColored("MatrixIterationStatement", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
PrintExpression(node.target.get(), "Target", false);
PrintStatement(node.body.get(), "Body", true);
DecreaseIndent();
}
// ===== 函数和声明 =====
void DebugPrinter::VisitFunctionDefinition(FunctionDefinition& node)
{
PrintIndent();
PrintColored("FunctionDefinition: ", Color::BrightCyan);
PrintColored("\"" + node.name + "\"", Color::Green);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.location);
}
os_ << "\n";
IncreaseIndent();
if (!node.parameters.empty())
{
PrintIndent();
PrintColored("Parameters:", Color::Yellow);
os_ << "\n";
IncreaseIndent();
for (size_t i = 0; i < node.parameters.size(); ++i)
{
if (node.parameters[i])
{
PrintParameter(*node.parameters[i], i == node.parameters.size() - 1);
}
}
DecreaseIndent();
}
PrintIndent();
std::string overload = node.is_overload ? "true" : "false";
PrintColored("Overload: " + overload, Color::Cyan);
os_ << "\n";
DecreaseIndent();
if (node.return_type)
PrintKeyValue("ReturnType", node.return_type->name);
if (node.body)
PrintStatement(node.body.get(), "Body", true);
DecreaseIndent();
}
void DebugPrinter::VisitFunctionDeclaration(FunctionDeclaration& node)
{
PrintIndent();
PrintColored("FunctionDeclaration: ", Color::BrightCyan);
PrintColored("\"" + node.name + "\"", Color::Green);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
IncreaseIndent();
if (!node.parameters.empty())
{
PrintIndent();
PrintColored("Parameters:", Color::Yellow);
os_ << "\n";
IncreaseIndent();
for (size_t i = 0; i < node.parameters.size(); ++i)
{
if (node.parameters[i])
{
PrintParameter(*node.parameters[i], i == node.parameters.size() - 1);
}
}
DecreaseIndent();
}
if (node.return_type)
{
PrintKeyValue("ReturnType", node.return_type->name);
}
DecreaseIndent();
}
void DebugPrinter::VisitVarDeclaration(VarDeclaration& node)
{
PrintIndent();
PrintColored("VarDeclaration: ", Color::BrightCyan);
PrintColored("\"" + node.name + "\"", Color::Green);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.location);
}
os_ << "\n";
IncreaseIndent();
if (node.type)
{
PrintKeyValue("Type", node.type->name);
}
if (node.initial_value)
{
PrintExpression(node.initial_value.get(), "InitialValue", true);
}
DecreaseIndent();
}
void DebugPrinter::VisitStaticDeclaration(StaticDeclaration& node)
{
PrintIndent();
PrintColored("StaticDeclaration: ", Color::BrightCyan);
PrintColored("\"" + node.name + "\"", Color::Green);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.location);
}
os_ << "\n";
IncreaseIndent();
if (node.type)
{
PrintKeyValue("Type", node.type->name);
}
if (node.initial_value)
{
PrintExpression(node.initial_value.get(), "Initializer", true);
}
DecreaseIndent();
}
void DebugPrinter::VisitGlobalDeclaration(GlobalDeclaration& node)
{
PrintIndent();
PrintColored("GlobalDeclaration: ", Color::BrightCyan);
PrintColored("\"" + node.name + "\"", Color::Green);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.location);
}
os_ << "\n";
IncreaseIndent();
if (node.type)
{
PrintKeyValue("Type", node.type->name);
}
if (node.initial_value)
{
PrintExpression(node.initial_value.get(), "Initializer", true);
}
DecreaseIndent();
}
void DebugPrinter::VisitConstDeclaration(ConstDeclaration& node)
{
PrintIndent();
PrintColored("ConstDeclaration: ", Color::BrightCyan);
PrintColored("\"" + node.name + "\"", Color::Green);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.location);
}
os_ << "\n";
IncreaseIndent();
if (node.type)
{
PrintKeyValue("Type", node.type->name);
}
if (node.value)
{
PrintExpression(node.value.get(), "Value", true);
}
DecreaseIndent();
}
void DebugPrinter::VisitFieldDeclaration(FieldDeclaration& node)
{
PrintIndent();
PrintColored("FieldDeclaration: ", Color::BrightCyan);
PrintColored("\"" + node.name + "\"", Color::Green);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.location);
}
os_ << "\n";
IncreaseIndent();
if (node.type)
{
PrintKeyValue("Type", node.type->name);
}
if (node.initial_value)
{
PrintExpression(node.initial_value.get(), "Initializer", true);
}
DecreaseIndent();
}
// ===== 条件编译 =====
void DebugPrinter::VisitCompilerDirective(CompilerDirective& node)
{
PrintIndent();
PrintColored("CompilerDirective: ", Color::BrightCyan);
PrintColored("\"" + node.name + "\"", Color::Green);
if (node.switch_value)
{
os_ << " " << GetColor(Color::Magenta) << *node.switch_value << GetColor(Color::Reset);
}
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.location);
}
os_ << "\n";
}
void DebugPrinter::VisitConditionalBlock(ConditionalBlock& node)
{
PrintIndent();
PrintColored("ConditionalBlock: ", Color::BrightCyan);
PrintConditionalCompilationType(node.type);
os_ << " " << GetColor(Color::Green) << node.name << GetColor(Color::Reset);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.location);
}
os_ << "\n";
IncreaseIndent();
if (!node.consequence.empty())
{
PrintIndent();
PrintColored("Consequence:", Color::Yellow);
os_ << "\n";
IncreaseIndent();
PrintStatements(node.consequence);
DecreaseIndent();
}
if (!node.alternative.empty())
{
PrintIndent();
PrintColored("Alternative:", Color::Yellow);
os_ << "\n";
IncreaseIndent();
PrintStatements(node.alternative);
DecreaseIndent();
}
DecreaseIndent();
}
void DebugPrinter::VisitConditionalDirective(ConditionalDirective& node)
{
PrintIndent();
PrintColored("ConditionalDirective: ", Color::BrightCyan);
PrintConditionalCompilationType(node.type);
os_ << " " << GetColor(Color::Green) << node.name << GetColor(Color::Reset);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.location);
}
os_ << "\n";
}
void DebugPrinter::VisitTSLXBlock(TSLXBlock& node)
{
PrintIndent();
PrintColored("TSLXBlock", Color::BrightCyan);
if (options_.show_location)
{
os_ << " ";
PrintLocation(node.span);
}
os_ << "\n";
// TSLXBlock 的具体内容未定义,暂时只打印节点名称
}
// ===== 便捷函数实现 =====
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);
}
}