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

1112 lines
36 KiB
C++

#include <iomanip>
#include <algorithm>
#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<SymbolKind, std::vector<const SymbolDefinition*>> by_kind;
for (const auto* def : all_defs)
{
by_kind[def->kind].push_back(def);
}
// 定义固定的类型顺序
std::vector<SymbolKind> 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<SymbolId> 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<const SymbolDefinition*> 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<const SymbolDefinition*> 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<std::pair<std::string, SymbolId>> 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<std::pair<ScopeId, const ScopeInfo*>> 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<const SymbolDefinition*> 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<const SymbolDefinition*> 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<const SymbolDefinition*> 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<SymbolId> 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