#include #include #include "./debug_printer.hpp" namespace lsp::language::symbol::debug { // ==================== PrintOptions ==================== PrintOptions PrintOptions::Default() { return PrintOptions{}; } PrintOptions PrintOptions::Compact() { PrintOptions opts; opts.compact_mode = true; opts.show_details = false; opts.show_children = false; opts.indent_size = 1; return opts; } PrintOptions PrintOptions::Verbose() { PrintOptions opts; opts.show_details = true; opts.show_children = true; opts.show_references = true; return opts; } PrintOptions PrintOptions::NoColor() { PrintOptions opts; opts.use_color = false; return opts; } // ==================== Statistics ==================== void Statistics::Compute(const SymbolTable& table) { auto all_defs = table.GetAllDefinitions(); total_symbols = all_defs.size(); symbol_counts.clear(); for (const auto* def : all_defs) { symbol_counts[def->kind]++; auto refs = table.GetReferences(def->id); if (refs && !refs->empty()) { symbols_with_refs++; total_references += refs->size(); if (refs->size() > max_references) { max_references = refs->size(); most_referenced = def->id; } } } // 统计作用域 const auto& all_scopes = table.GetScopeManager().GetAllScopes(); total_scopes = all_scopes.size(); for (const auto& [id, info] : all_scopes) { scope_counts[info.kind]++; } } void Statistics::Print(std::ostream& os, bool use_color) const { auto color = [use_color](const char* code) { return use_color ? code : ""; }; os << "\n"; os << color(Color::Bold) << "╔════════════════════════════════════════════════════════════╗\n"; os << "║ STATISTICS ║\n"; os << "╚════════════════════════════════════════════════════════════╝" << color(Color::Reset) << "\n\n"; // 总体统计 os << color(Color::Bold) << "Overview:" << color(Color::Reset) << "\n"; os << " Total Symbols: " << color(Color::Cyan) << total_symbols << color(Color::Reset) << "\n"; os << " Total Scopes: " << color(Color::Cyan) << total_scopes << color(Color::Reset) << "\n"; os << " Total References: " << color(Color::Cyan) << total_references << color(Color::Reset) << "\n"; os << " Symbols w/ Refs: " << color(Color::Green) << symbols_with_refs << color(Color::Reset) << "\n"; if (most_referenced != kInvalidSymbolId) { os << " Most Referenced: " << color(Color::Yellow) << "ID=" << most_referenced << " (" << max_references << " refs)" << color(Color::Reset) << "\n"; } os << "\n"; // 符号类型分布 os << color(Color::Bold) << "Symbol Distribution:" << color(Color::Reset) << "\n"; struct KindInfo { SymbolKind kind; const char* name; const char* icon; }; KindInfo kinds[] = { { SymbolKind::Module, "Modules", "📦" }, { SymbolKind::Namespace, "Namespace", "🗃️" }, { SymbolKind::Class, "Classes", "🏛️" }, { SymbolKind::Interface, "Interfaces", "🔌" }, { SymbolKind::Struct, "Structs", "📐" }, { SymbolKind::Enum, "Enums", "🔢" }, { SymbolKind::Function, "Functions", "🎄" }, { SymbolKind::Method, "Methods", "🪀" }, { SymbolKind::Constructor, "Constructors", "🔨" }, { SymbolKind::Property, "Properties", "📋" }, { SymbolKind::Field, "Fields", "📌" }, { SymbolKind::Variable, "Variables", "📊" }, { SymbolKind::Constant, "Constants", "🔒" } }; for (const auto& kind_info : kinds) { auto it = symbol_counts.find(kind_info.kind); if (it != symbol_counts.end() && it->second > 0) { os << " " << kind_info.icon << " " << std::setw(15) << std::left << kind_info.name << ": " << color(Color::BrightBlue) << std::setw(5) << std::right << it->second << color(Color::Reset) << "\n"; } } os << "\n"; // 作用域分布 if (!scope_counts.empty()) { os << color(Color::Bold) << "Scope Distribution:" << color(Color::Reset) << "\n"; struct ScopeKindInfo { ScopeKind kind; const char* name; }; ScopeKindInfo scope_kinds[] = { { ScopeKind::Global, "Global" }, { ScopeKind::Unit, "Unit" }, { ScopeKind::Class, "Class" }, { ScopeKind::Function, "Function" }, { ScopeKind::Block, "Block" } }; for (const auto& scope_info : scope_kinds) { auto it = scope_counts.find(scope_info.kind); if (it != scope_counts.end() && it->second > 0) { os << " " << std::setw(15) << std::left << scope_info.name << ": " << color(Color::BrightMagenta) << std::setw(5) << std::right << it->second << color(Color::Reset) << "\n"; } } os << "\n"; } } // ==================== DebugPrinter ==================== DebugPrinter::DebugPrinter(const SymbolTable& table, const PrintOptions& options) : table_(table), options_(options) { stats_.Compute(table); } // ===== 顶层打印 ===== void DebugPrinter::PrintAll(std::ostream& os) { PrintHeader("SYMBOL TABLE DUMP", os); PrintSubHeader("1. Overview", os); PrintOverview(os); PrintSubHeader("2. Symbol Definitions", os); PrintSymbolList(os); PrintSubHeader("3. Scope Hierarchy", os); PrintScopeHierarchy(os); PrintSubHeader("4. References", os); PrintAllReferences(os); PrintSubHeader("5. Inheritance", os); PrintAllInheritance(os); PrintSubHeader("6. Call Graph", os); PrintAllCalls(os); PrintSubHeader("7. Statistics", os); PrintStatistics(os); } void DebugPrinter::PrintOverview(std::ostream& os) { auto all_defs = table_.GetAllDefinitions(); os << "\n"; os << Color(Color::Bold) << "Symbol Table Overview" << Color(Color::Reset) << "\n"; os << " Total Symbols: " << Color(Color::Cyan) << all_defs.size() << Color(Color::Reset) << "\n"; os << " Total Scopes: " << Color(Color::Cyan) << stats_.total_scopes << Color(Color::Reset) << "\n"; os << "\n"; // 按类型分组显示 std::unordered_map> by_kind; for (const auto* def : all_defs) { by_kind[def->kind].push_back(def); } // 定义固定的类型顺序 std::vector kind_order = { SymbolKind::Module, SymbolKind::Class, SymbolKind::Interface, SymbolKind::Struct, SymbolKind::Enum, SymbolKind::Function, SymbolKind::Method, SymbolKind::Constructor, SymbolKind::Property, SymbolKind::Field, SymbolKind::Variable, SymbolKind::Constant }; // 按固定顺序遍历类型 for (const auto& kind : kind_order) { auto it = by_kind.find(kind); if (it == by_kind.end() || it->second.empty()) continue; auto& symbols = it->second; // 按位置排序同类型的符号 std::sort(symbols.begin(), symbols.end(), [](const SymbolDefinition* a, const SymbolDefinition* b) { if (a->location.start_line != b->location.start_line) return a->location.start_line < b->location.start_line; if (a->location.start_column != b->location.start_column) return a->location.start_column < b->location.start_column; return true; }); os << " " << SymbolIcon(kind) << " " << Color(Color::Bold) << FormatSymbolKind(kind) << Color(Color::Reset) << " (" << symbols.size() << ")\n"; if (!options_.compact_mode) { for (const auto* sym : symbols) { os << " " << Color(Color::Dim) << "• " << Color(Color::Reset) << ColorizeSymbolName(sym->name, kind); if (options_.show_location) { os << " " << Color(Color::Dim) << FormatLocation(sym->location) << Color(Color::Reset); } os << "\n"; } } } os << "\n"; } void DebugPrinter::PrintStatistics(std::ostream& os) { stats_.Print(os, options_.use_color); } // ===== 符号打印 ===== void DebugPrinter::PrintSymbol(SymbolId id, std::ostream& os, int depth) { const auto* def = table_.GetDefinition(id); if (!def) return; os << Indent(depth); os << SymbolIcon(def->kind) << " "; os << ColorizeSymbolName(def->name, def->kind); if (options_.show_location) { os << " " << Color(Color::Dim) << FormatLocation(def->location) << Color(Color::Reset); } os << "\n"; if (options_.show_details && !options_.compact_mode) { os << Indent(depth + 1) << Color(Color::Dim) << "Kind: " << Color(Color::Reset) << FormatSymbolKind(def->kind) << "\n"; if (def->type_hint) { os << Indent(depth + 1) << Color(Color::Dim) << "Type: " << Color(Color::Reset) << *def->type_hint << "\n"; } if (!def->detail.empty()) { os << Indent(depth + 1) << Color(Color::Dim) << "Detail: " << Color(Color::Reset) << def->detail << "\n"; } if (def->access_modifier) { const char* access_str = "public"; switch (*def->access_modifier) { case ast::AccessModifier::kPublic: access_str = "public"; break; case ast::AccessModifier::kProtected: access_str = "protected"; break; case ast::AccessModifier::kPrivate: access_str = "private"; break; } os << Indent(depth + 1) << Color(Color::Dim) << "Access: " << Color(Color::Reset) << access_str << "\n"; } } } void DebugPrinter::PrintSymbolTree(SymbolId id, std::ostream& os, int depth) { if (options_.max_depth >= 0 && depth > options_.max_depth) return; PrintSymbol(id, os, depth); if (options_.show_children) { auto children = table_.GetChildren(id); // 按位置排序子符号 std::vector sorted_children(children.begin(), children.end()); std::sort(sorted_children.begin(), sorted_children.end(), [this](SymbolId a, SymbolId b) { const auto* def_a = table_.GetDefinition(a); const auto* def_b = table_.GetDefinition(b); if (!def_a || !def_b) return false; if (def_a->location.start_line != def_b->location.start_line) return def_a->location.start_line < def_b->location.start_line; if (def_a->location.start_column != def_b->location.start_column) return def_a->location.start_column < def_b->location.start_column; return true; }); for (SymbolId child_id : sorted_children) { PrintSymbolTree(child_id, os, depth + 1); } } } void DebugPrinter::PrintSymbolList(std::ostream& os) { auto all_defs = table_.GetAllDefinitions(); if (all_defs.empty()) { os << Color(Color::Dim) << " (no symbols)\n" << Color(Color::Reset); return; } // 按层级排序(顶层优先) std::vector top_level; for (const auto* def : all_defs) { if (!def->parent_id) top_level.push_back(def); } // 按位置排序顶层符号 std::sort(top_level.begin(), top_level.end(), [](const SymbolDefinition* a, const SymbolDefinition* b) { if (a->location.start_line != b->location.start_line) return a->location.start_line < b->location.start_line; if (a->location.start_column != b->location.start_column) return a->location.start_column < b->location.start_column; return true; }); for (const auto* def : top_level) { PrintSymbolTree(def->id, os, 0); } } void DebugPrinter::PrintSymbolsByKind(SymbolKind kind, std::ostream& os) { auto all_defs = table_.GetAllDefinitions(); os << "\n" << Color(Color::Bold) << FormatSymbolKind(kind) << "s:" << Color(Color::Reset) << "\n\n"; // 收集并排序符号 std::vector symbols; for (const auto* def : all_defs) { if (def->kind == kind) { symbols.push_back(def); } } if (symbols.empty()) { os << Color(Color::Dim) << " (none)\n" << Color(Color::Reset); } else { // 按位置排序 std::sort(symbols.begin(), symbols.end(), [](const SymbolDefinition* a, const SymbolDefinition* b) { if (a->location.start_line != b->location.start_line) return a->location.start_line < b->location.start_line; if (a->location.start_column != b->location.start_column) return a->location.start_column < b->location.start_column; return true; }); for (const auto* def : symbols) { PrintSymbol(def->id, os, 0); } } os << "\n"; } // ===== 作用域打印 ===== void DebugPrinter::PrintScope(ScopeId id, std::ostream& os, int depth) { const auto* info = table_.GetScopeManager().GetScopeInfo(id); if (!info) return; os << Indent(depth); os << "🔷 " << Color(Color::Bold) << FormatScopeKind(info->kind) << Color(Color::Reset); os << " (id=" << id << ")"; if (options_.show_location) { os << " " << Color(Color::Dim) << FormatLocation(info->range) << Color(Color::Reset); } os << "\n"; if (!options_.compact_mode && !info->symbols.empty()) { os << Indent(depth + 1) << Color(Color::Dim) << "Symbols: " << info->symbols.size() << Color(Color::Reset) << "\n"; // 收集符号并按位置排序 std::vector> sorted_symbols( info->symbols.begin(), info->symbols.end()); std::sort(sorted_symbols.begin(), sorted_symbols.end(), [this](const auto& a, const auto& b) { // 按符号定义的位置排序 const auto* def_a = table_.GetDefinition(a.second); const auto* def_b = table_.GetDefinition(b.second); if (!def_a || !def_b) return false; if (def_a->location.start_line != def_b->location.start_line) return def_a->location.start_line < def_b->location.start_line; if (def_a->location.start_column != def_b->location.start_column) return def_a->location.start_column < def_b->location.start_column; return true; }); for (const auto& [name, sym_id] : sorted_symbols) { os << Indent(depth + 2) << "• " << name << "\n"; } } } void DebugPrinter::PrintScopeTree(ScopeId id, std::ostream& os, int depth) { if (options_.max_depth >= 0 && depth > options_.max_depth) return; PrintScope(id, os, depth); // 查找并收集子作用域 const auto& all_scopes = table_.GetScopeManager().GetAllScopes(); std::vector> children; for (const auto& [child_id, info] : all_scopes) { if (info.parent_scope_id && *info.parent_scope_id == id) { children.push_back({ child_id, &info }); } } // 按位置排序子作用域 std::sort(children.begin(), children.end(), [](const auto& a, const auto& b) { if (a.second->range.start_line != b.second->range.start_line) return a.second->range.start_line < b.second->range.start_line; if (a.second->range.start_column != b.second->range.start_column) return a.second->range.start_column < b.second->range.start_column; return true; }); // 递归打印子作用域 for (const auto& [child_id, info] : children) { PrintScopeTree(child_id, os, depth + 1); } } void DebugPrinter::PrintScopeHierarchy(std::ostream& os) { ScopeId global_scope = table_.GetGlobalScope(); if (global_scope == kInvalidScopeId) { os << Color(Color::Dim) << " (no scopes)\n" << Color(Color::Reset); return; } PrintScopeTree(global_scope, os, 0); } // ===== 关系打印 ===== void DebugPrinter::PrintReferences(SymbolId id, std::ostream& os) { const auto* def = table_.GetDefinition(id); if (!def) return; os << "\n" << Color(Color::Bold) << "References for: " << def->name << Color(Color::Reset) << "\n"; auto refs = table_.GetReferences(id); if (!refs || refs->empty()) { os << Color(Color::Dim) << " (no references)\n" << Color(Color::Reset); return; } os << " Total: " << refs->size() << "\n\n"; for (const auto& ref : *refs) { os << " "; if (ref.is_definition) os << Color(Color::Green) << "[DEF]" << Color(Color::Reset) << " "; else if (ref.is_write) os << Color(Color::Yellow) << "[WRITE]" << Color(Color::Reset) << " "; else os << Color(Color::Cyan) << "[READ]" << Color(Color::Reset) << " "; os << FormatLocation(ref.location) << "\n"; } os << "\n"; } void DebugPrinter::PrintInheritance(SymbolId class_id, std::ostream& os) { const auto* def = table_.GetDefinition(class_id); if (!def || def->kind != SymbolKind::Class) return; os << "\n" << Color(Color::Bold) << "Inheritance for: " << def->name << Color(Color::Reset) << "\n\n"; // 基类 auto bases = table_.GetBaseClasses(class_id); if (bases && !bases->empty()) { os << " " << Color(Color::Green) << "Base Classes:" << Color(Color::Reset) << "\n"; for (SymbolId base_id : *bases) { const auto* base_def = table_.GetDefinition(base_id); if (base_def) { os << " ↑ " << base_def->name << "\n"; } } } // 派生类 auto derived = table_.GetDerivedClasses(class_id); if (derived && !derived->empty()) { os << " " << Color(Color::Yellow) << "Derived Classes:" << Color(Color::Reset) << "\n"; for (SymbolId derived_id : *derived) { const auto* derived_def = table_.GetDefinition(derived_id); if (derived_def) { os << " ↓ " << derived_def->name << "\n"; } } } os << "\n"; } void DebugPrinter::PrintCallGraph(SymbolId function_id, std::ostream& os) { const auto* def = table_.GetDefinition(function_id); if (!def) return; os << "\n" << Color(Color::Bold) << "Call Graph for: " << def->name << Color(Color::Reset) << "\n\n"; // 调用者 auto callers = table_.GetCallers(function_id); if (callers && !callers->empty()) { os << " " << Color(Color::Green) << "Called by:" << Color(Color::Reset) << "\n"; for (const auto& rel : *callers) { const auto* caller_def = table_.GetDefinition(rel.caller); if (caller_def) { os << " ← " << caller_def->name << " " << Color(Color::Dim) << FormatLocation(rel.call_location) << Color(Color::Reset) << "\n"; } } } // 被调用的 auto callees = table_.GetCallees(function_id); if (callees && !callees->empty()) { os << " " << Color(Color::Yellow) << "Calls:" << Color(Color::Reset) << "\n"; for (const auto& rel : *callees) { const auto* callee_def = table_.GetDefinition(rel.callee); if (callee_def) { os << " → " << callee_def->name << " " << Color(Color::Dim) << FormatLocation(rel.call_location) << Color(Color::Reset) << "\n"; } } } os << "\n"; } void DebugPrinter::PrintAllReferences(std::ostream& os) { auto all_defs = table_.GetAllDefinitions(); // 按位置排序 std::vector sorted_defs(all_defs.begin(), all_defs.end()); std::sort(sorted_defs.begin(), sorted_defs.end(), [](const SymbolDefinition* a, const SymbolDefinition* b) { if (a->location.start_line != b->location.start_line) return a->location.start_line < b->location.start_line; if (a->location.start_column != b->location.start_column) return a->location.start_column < b->location.start_column; return true; }); for (const auto* def : sorted_defs) { auto refs = table_.GetReferences(def->id); if (refs && refs->size() > 1) // >1 因为定义本身算一个引用 { PrintReferences(def->id, os); } } } void DebugPrinter::PrintAllInheritance(std::ostream& os) { auto all_defs = table_.GetAllDefinitions(); // 按位置排序 std::vector sorted_defs(all_defs.begin(), all_defs.end()); std::sort(sorted_defs.begin(), sorted_defs.end(), [](const SymbolDefinition* a, const SymbolDefinition* b) { if (a->location.start_line != b->location.start_line) return a->location.start_line < b->location.start_line; if (a->location.start_column != b->location.start_column) return a->location.start_column < b->location.start_column; return true; }); bool found = false; for (const auto* def : sorted_defs) { if (def->kind == SymbolKind::Class) { auto bases = table_.GetBaseClasses(def->id); auto derived = table_.GetDerivedClasses(def->id); if ((bases && !bases->empty()) || (derived && !derived->empty())) { PrintInheritance(def->id, os); found = true; } } } if (!found) { os << Color(Color::Dim) << " (no inheritance relationships)\n" << Color(Color::Reset); } } void DebugPrinter::PrintAllCalls(std::ostream& os) { auto all_defs = table_.GetAllDefinitions(); // 按位置排序 std::vector sorted_defs(all_defs.begin(), all_defs.end()); std::sort(sorted_defs.begin(), sorted_defs.end(), [](const SymbolDefinition* a, const SymbolDefinition* b) { if (a->location.start_line != b->location.start_line) return a->location.start_line < b->location.start_line; if (a->location.start_column != b->location.start_column) return a->location.start_column < b->location.start_column; return true; }); bool found = false; for (const auto* def : sorted_defs) { if (def->kind == SymbolKind::Function || def->kind == SymbolKind::Method) { auto callers = table_.GetCallers(def->id); auto callees = table_.GetCallees(def->id); if ((callers && !callers->empty()) || (callees && !callees->empty())) { PrintCallGraph(def->id, os); found = true; } } } if (!found) { os << Color(Color::Dim) << " (no call relationships)\n" << Color(Color::Reset); } } // ===== 搜索和查询 ===== void DebugPrinter::FindAndPrint(const std::string& name, std::ostream& os) { auto symbols = table_.FindSymbolsByName(name); os << "\n" << Color(Color::Bold) << "Search results for: '" << name << "'" << Color(Color::Reset) << "\n"; os << "Found " << symbols.size() << " symbol(s)\n\n"; if (symbols.empty()) { os << Color(Color::Dim) << " (no matches)\n" << Color(Color::Reset); return; } // 按位置排序结果 std::vector sorted_symbols(symbols.begin(), symbols.end()); std::sort(sorted_symbols.begin(), sorted_symbols.end(), [this](SymbolId a, SymbolId b) { const auto* def_a = table_.GetDefinition(a); const auto* def_b = table_.GetDefinition(b); if (!def_a || !def_b) return false; if (def_a->location.start_line != def_b->location.start_line) return def_a->location.start_line < def_b->location.start_line; if (def_a->location.start_column != def_b->location.start_column) return def_a->location.start_column < def_b->location.start_column; return true; }); for (SymbolId id : sorted_symbols) { const auto* def = table_.GetDefinition(id); if (!def) continue; PrintSymbol(id, os, 0); if (options_.show_references) { PrintReferences(id, os); } os << "\n"; } } void DebugPrinter::FindAtLocation(const ast::Location& loc, std::ostream& os) { os << "\n" << Color(Color::Bold) << "Symbols at location: " << FormatLocation(loc) << Color(Color::Reset) << "\n\n"; // 查找符号 auto symbol_id = table_.FindSymbolAt(loc); if (symbol_id) { os << "Symbol: "; PrintSymbol(*symbol_id, os, 0); } else { os << "Symbol: " << Color(Color::Dim) << "(none)\n" << Color(Color::Reset); } // 查找作用域 auto scope_id = table_.FindScopeAt(loc); if (scope_id) { os << "Scope: "; PrintScope(*scope_id, os, 0); } else { os << "Scope: " << Color(Color::Dim) << "(none)\n" << Color(Color::Reset); } // 查找引用 auto ref_id = table_.FindReferenceAt(loc); if (ref_id) { os << "Reference to: "; PrintSymbol(*ref_id, os, 0); } os << "\n"; } // ===== 辅助方法 ===== std::string DebugPrinter::Indent(int depth) const { return std::string(depth * options_.indent_size, ' '); } std::string DebugPrinter::ColorizeSymbolKind(SymbolKind kind) const { if (!options_.use_color) return ""; switch (kind) { case SymbolKind::Module: return Color::BrightMagenta; case SymbolKind::Class: return Color::BrightYellow; case SymbolKind::Function: return Color::BrightBlue; case SymbolKind::Method: return Color::BrightCyan; case SymbolKind::Constructor: return Color::BrightGreen; case SymbolKind::Interface: return Color::BrightMagenta; case SymbolKind::Struct: return Color::BrightYellow; case SymbolKind::Enum: return Color::BrightCyan; case SymbolKind::Property: return Color::Magenta; case SymbolKind::Field: return Color::Yellow; case SymbolKind::Variable: return Color::White; case SymbolKind::Constant: return Color::BrightRed; default: return Color::Reset; } } std::string DebugPrinter::ColorizeSymbolName(const std::string& name, SymbolKind kind) const { if (!options_.use_color) return name; return std::string(ColorizeSymbolKind(kind)) + name + Color::Reset; } std::string DebugPrinter::FormatLocation(const ast::Location& loc) const { std::ostringstream oss; oss << "[" << loc.start_line << ":" << loc.start_column << "-" << loc.end_line << ":" << loc.end_column << "]"; return oss.str(); } std::string DebugPrinter::FormatSymbolKind(SymbolKind kind) const { switch (kind) { case SymbolKind::Module: return "Module"; case SymbolKind::Namespace: return "Namespace"; case SymbolKind::Class: return "Class"; case SymbolKind::Interface: return "Interface"; case SymbolKind::Struct: return "Struct"; case SymbolKind::Enum: return "Enum"; case SymbolKind::Function: return "Function"; case SymbolKind::Method: return "Method"; case SymbolKind::Constructor: return "Constructor"; case SymbolKind::Property: return "Property"; case SymbolKind::Field: return "Field"; case SymbolKind::Variable: return "Variable"; case SymbolKind::Constant: return "Constant"; default: return "Unknown"; } } std::string DebugPrinter::FormatScopeKind(ScopeKind kind) const { switch (kind) { case ScopeKind::Global: return "Global"; case ScopeKind::Unit: return "Unit"; case ScopeKind::Class: return "Class"; case ScopeKind::Function: return "Function"; case ScopeKind::Block: return "Block"; default: return "Unknown"; } } std::string DebugPrinter::SymbolIcon(SymbolKind kind) const { if (!options_.use_color) return ""; switch (kind) { case SymbolKind::Module: return "📦"; case SymbolKind::Namespace: return "🗃️"; case SymbolKind::Class: return "🏛️"; case SymbolKind::Interface: return "🔌"; case SymbolKind::Struct: return "📐"; case SymbolKind::Enum: return "🔢"; case SymbolKind::Function: return "🎄"; case SymbolKind::Method: return "🪀"; case SymbolKind::Constructor: return "🔨"; case SymbolKind::Property: return "📋"; case SymbolKind::Field: return "📌"; case SymbolKind::Variable: return "📊"; case SymbolKind::Constant: return "🔒"; default: return "•"; } } void DebugPrinter::PrintSeparator(std::ostream& os, char ch, int width) const { os << std::string(width, ch) << "\n"; } void DebugPrinter::PrintHeader(const std::string& title, std::ostream& os) const { os << "\n"; os << Color(Color::Bold) << "╔" << std::string(78, '=') << "╗\n"; os << "║ " << std::setw(74) << std::left << title << " ║\n"; os << "╚" << std::string(78, '=') << "╝" << Color(Color::Reset) << "\n\n"; } void DebugPrinter::PrintSubHeader(const std::string& title, std::ostream& os) const { os << "\n"; os << Color(Color::Bold) << Color(Color::BrightCyan) << "┌─ " << title << " " << std::string(73 - title.length(), '-') << "\n" << Color(Color::Reset); } std::string DebugPrinter::Color(const char* color_code) const { return options_.use_color ? color_code : ""; } std::string DebugPrinter::Bold(const std::string& text) const { if (!options_.use_color) return text; return std::string(Color::Bold) + text + Color::Reset; } std::string DebugPrinter::Dim(const std::string& text) const { if (!options_.use_color) return text; return std::string(Color::Dim) + text + Color::Reset; } // ==================== 快速打印函数 ==================== void Print(const SymbolTable& table, std::ostream& os) { DebugPrinter printer(table); printer.PrintAll(os); } void PrintOverview(const SymbolTable& table, std::ostream& os) { DebugPrinter printer(table); printer.PrintOverview(os); } void PrintStats(const SymbolTable& table, std::ostream& os) { DebugPrinter printer(table); printer.PrintStatistics(os); } void PrintSymbolTree(const SymbolTable& table, std::ostream& os) { DebugPrinter printer(table); printer.PrintSymbolList(os); } void PrintScopeTree(const SymbolTable& table, std::ostream& os) { DebugPrinter printer(table); printer.PrintScopeHierarchy(os); } void Find(const SymbolTable& table, const std::string& name, std::ostream& os) { DebugPrinter printer(table); printer.FindAndPrint(name, os); } void PrintCompact(const SymbolTable& table, std::ostream& os) { DebugPrinter printer(table, PrintOptions::Compact()); printer.PrintOverview(os); printer.PrintStatistics(os); } void PrintVerbose(const SymbolTable& table, std::ostream& os) { DebugPrinter printer(table, PrintOptions::Verbose()); printer.PrintAll(os); } } // namespace lsp::language::symbol::debug