✨ 新增语义模块
♻️ 重构符号表,职责更清晰单一 🐛 同步修复`test_symbol`
This commit is contained in:
@@ -27,9 +27,6 @@ set(SOURCES
|
||||
../../src/language/symbol/table.cpp
|
||||
../../src/language/symbol/index/location.cpp
|
||||
../../src/language/symbol/index/scope.cpp
|
||||
../../src/language/symbol/graph/call.cpp
|
||||
../../src/language/symbol/graph/inheritance.cpp
|
||||
../../src/language/symbol/graph/reference.cpp
|
||||
../../src/tree-sitter/scanner.c
|
||||
../../src/tree-sitter/parser.c)
|
||||
|
||||
|
||||
@@ -87,7 +87,6 @@ namespace lsp::language::symbol::debug
|
||||
PrintOptions opts;
|
||||
opts.show_details = true;
|
||||
opts.show_children = true;
|
||||
opts.show_references = true;
|
||||
return opts;
|
||||
}
|
||||
|
||||
@@ -107,27 +106,11 @@ namespace lsp::language::symbol::debug
|
||||
|
||||
symbol_counts.clear();
|
||||
scope_counts.clear();
|
||||
symbols_with_refs = 0;
|
||||
total_references = 0;
|
||||
max_references = 0;
|
||||
most_referenced = kInvalidSymbolId;
|
||||
|
||||
for (const auto& ref : all_defs)
|
||||
{
|
||||
const auto& sym = ref.get();
|
||||
symbol_counts[sym.kind()]++;
|
||||
|
||||
const auto& refs = table.references().references(sym.id());
|
||||
if (!refs.empty())
|
||||
{
|
||||
symbols_with_refs++;
|
||||
total_references += refs.size();
|
||||
if (refs.size() > max_references)
|
||||
{
|
||||
max_references = refs.size();
|
||||
most_referenced = sym.id();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const auto& scopes = table.scopes().all_scopes();
|
||||
@@ -153,15 +136,6 @@ namespace lsp::language::symbol::debug
|
||||
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";
|
||||
@@ -507,12 +481,6 @@ namespace lsp::language::symbol::debug
|
||||
}
|
||||
}
|
||||
|
||||
const auto& refs = table_.references().references(symbol.id());
|
||||
if (options_.show_references && !refs.empty())
|
||||
{
|
||||
os << " " << Dim("[refs: " + std::to_string(refs.size()) + "]");
|
||||
}
|
||||
|
||||
os << "\n";
|
||||
},
|
||||
symbol.data());
|
||||
@@ -713,135 +681,6 @@ namespace lsp::language::symbol::debug
|
||||
PrintScopeTree(global, os, 0);
|
||||
}
|
||||
|
||||
void DebugPrinter::PrintReferences(SymbolId id, std::ostream& os)
|
||||
{
|
||||
const auto& refs = table_.references().references(id);
|
||||
if (refs.empty())
|
||||
return;
|
||||
|
||||
PrintSubHeader("References for symbol " + std::to_string(id), os);
|
||||
for (const auto& ref : refs)
|
||||
{
|
||||
os << " - " << FormatLocation(ref.location);
|
||||
if (ref.is_definition)
|
||||
os << " (def)";
|
||||
if (ref.is_write)
|
||||
os << " (write)";
|
||||
os << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void DebugPrinter::PrintInheritance(SymbolId class_id, std::ostream& os)
|
||||
{
|
||||
const auto& bases = table_.inheritance().base_classes(class_id);
|
||||
const auto& derived = table_.inheritance().derived_classes(class_id);
|
||||
|
||||
PrintSubHeader("Inheritance for class " + std::to_string(class_id), os);
|
||||
if (bases.empty() && derived.empty())
|
||||
{
|
||||
os << " (no inheritance info)\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!bases.empty())
|
||||
{
|
||||
os << " Base classes: ";
|
||||
for (size_t i = 0; i < bases.size(); ++i)
|
||||
{
|
||||
os << bases[i];
|
||||
if (i + 1 < bases.size())
|
||||
os << ", ";
|
||||
}
|
||||
os << "\n";
|
||||
}
|
||||
if (!derived.empty())
|
||||
{
|
||||
os << " Derived classes: ";
|
||||
for (size_t i = 0; i < derived.size(); ++i)
|
||||
{
|
||||
os << derived[i];
|
||||
if (i + 1 < derived.size())
|
||||
os << ", ";
|
||||
}
|
||||
os << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void DebugPrinter::PrintCallGraph(SymbolId function_id, std::ostream& os)
|
||||
{
|
||||
const auto& incoming = table_.calls().callers(function_id);
|
||||
const auto& outgoing = table_.calls().callees(function_id);
|
||||
PrintSubHeader("Call graph for " + std::to_string(function_id), os);
|
||||
if (incoming.empty() && outgoing.empty())
|
||||
{
|
||||
os << " (no call info)\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!incoming.empty())
|
||||
{
|
||||
os << " Called by: ";
|
||||
for (size_t i = 0; i < incoming.size(); ++i)
|
||||
{
|
||||
os << incoming[i].caller;
|
||||
if (i + 1 < incoming.size())
|
||||
os << ", ";
|
||||
}
|
||||
os << "\n";
|
||||
}
|
||||
|
||||
if (!outgoing.empty())
|
||||
{
|
||||
os << " Calls: ";
|
||||
for (size_t i = 0; i < outgoing.size(); ++i)
|
||||
{
|
||||
os << outgoing[i].callee;
|
||||
if (i + 1 < outgoing.size())
|
||||
os << ", ";
|
||||
}
|
||||
os << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void DebugPrinter::PrintAllReferences(std::ostream& os)
|
||||
{
|
||||
PrintHeader("References", os);
|
||||
auto all_defs = table_.all_definitions();
|
||||
for (const auto& ref : all_defs)
|
||||
{
|
||||
const auto& sym = ref.get();
|
||||
PrintReferences(sym.id(), os);
|
||||
}
|
||||
}
|
||||
|
||||
void DebugPrinter::PrintAllInheritance(std::ostream& os)
|
||||
{
|
||||
PrintHeader("Inheritance Graph", os);
|
||||
auto all_defs = table_.all_definitions();
|
||||
for (const auto& ref : all_defs)
|
||||
{
|
||||
const auto& sym = ref.get();
|
||||
if (sym.kind() == SymbolKind::Class)
|
||||
{
|
||||
PrintInheritance(sym.id(), os);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DebugPrinter::PrintAllCalls(std::ostream& os)
|
||||
{
|
||||
PrintHeader("Call Graph", os);
|
||||
auto all_defs = table_.all_definitions();
|
||||
for (const auto& ref : all_defs)
|
||||
{
|
||||
const auto& sym = ref.get();
|
||||
if (sym.kind() == SymbolKind::Function || sym.kind() == SymbolKind::Method)
|
||||
{
|
||||
PrintCallGraph(sym.id(), os);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DebugPrinter::FindAndPrint(const std::string& name, std::ostream& os)
|
||||
{
|
||||
PrintHeader("Search: " + name, os);
|
||||
@@ -855,7 +694,6 @@ namespace lsp::language::symbol::debug
|
||||
for (auto id : matches)
|
||||
{
|
||||
PrintSymbol(id, os);
|
||||
PrintReferences(id, os);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -875,7 +713,6 @@ namespace lsp::language::symbol::debug
|
||||
PrintHeader("Overview", os);
|
||||
os << "Symbols: " << stats_.total_symbols << "\n";
|
||||
os << "Scopes: " << stats_.total_scopes << "\n";
|
||||
os << "Refs: " << stats_.total_references << "\n";
|
||||
}
|
||||
|
||||
void DebugPrinter::PrintStatistics(std::ostream& os)
|
||||
@@ -888,13 +725,6 @@ namespace lsp::language::symbol::debug
|
||||
PrintOverview(os);
|
||||
PrintSymbolList(os);
|
||||
PrintScopeHierarchy(os);
|
||||
|
||||
if (options_.show_references)
|
||||
{
|
||||
PrintAllReferences(os);
|
||||
}
|
||||
PrintAllInheritance(os);
|
||||
PrintAllCalls(os);
|
||||
PrintStatistics(os);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,10 +4,13 @@
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include "../../src/language/symbol/table.hpp"
|
||||
#include "../../src/protocol/protocol.hpp"
|
||||
|
||||
namespace lsp::language::symbol::debug
|
||||
{
|
||||
|
||||
using SymbolKind = protocol::SymbolKind;
|
||||
|
||||
// ==================== 打印选项 ====================
|
||||
|
||||
struct PrintOptions
|
||||
@@ -16,7 +19,6 @@ namespace lsp::language::symbol::debug
|
||||
bool show_location = true; // 显示位置信息
|
||||
bool show_details = true; // 显示详细信息
|
||||
bool show_children = true; // 显示子符号
|
||||
bool show_references = false; // 显示引用列表
|
||||
bool compact_mode = false; // 紧凑模式
|
||||
int indent_size = 2; // 缩进大小
|
||||
int max_depth = -1; // 最大深度 (-1 = 无限制)
|
||||
@@ -33,15 +35,10 @@ namespace lsp::language::symbol::debug
|
||||
{
|
||||
size_t total_symbols = 0;
|
||||
size_t total_scopes = 0;
|
||||
size_t total_references = 0;
|
||||
|
||||
std::unordered_map<SymbolKind, size_t> symbol_counts;
|
||||
std::unordered_map<ScopeKind, size_t> scope_counts;
|
||||
|
||||
size_t symbols_with_refs = 0;
|
||||
size_t max_references = 0;
|
||||
SymbolId most_referenced = kInvalidSymbolId;
|
||||
|
||||
void Compute(const SymbolTable& table);
|
||||
void Print(std::ostream& os, bool use_color = true) const;
|
||||
};
|
||||
@@ -69,14 +66,6 @@ namespace lsp::language::symbol::debug
|
||||
void PrintScopeTree(ScopeId id, std::ostream& os = std::cout, int depth = 0);
|
||||
void PrintScopeHierarchy(std::ostream& os = std::cout);
|
||||
|
||||
// ===== 关系打印 =====
|
||||
void PrintReferences(SymbolId id, std::ostream& os = std::cout);
|
||||
void PrintInheritance(SymbolId class_id, std::ostream& os = std::cout);
|
||||
void PrintCallGraph(SymbolId function_id, std::ostream& os = std::cout);
|
||||
void PrintAllReferences(std::ostream& os = std::cout);
|
||||
void PrintAllInheritance(std::ostream& os = std::cout);
|
||||
void PrintAllCalls(std::ostream& os = std::cout);
|
||||
|
||||
// ===== 搜索和查询 =====
|
||||
void FindAndPrint(const std::string& name, std::ostream& os = std::cout);
|
||||
void FindAtLocation(const ast::Location& loc, std::ostream& os = std::cout);
|
||||
|
||||
@@ -115,9 +115,6 @@ struct Options
|
||||
bool print_all = true;
|
||||
bool print_definitions = false;
|
||||
bool print_scopes = false;
|
||||
bool print_references = false;
|
||||
bool print_inheritance = false;
|
||||
bool print_calls = false;
|
||||
bool compact_mode = false;
|
||||
bool statistics_only = false;
|
||||
std::string search_symbol;
|
||||
@@ -135,9 +132,6 @@ void PrintUsage(const char* program_name)
|
||||
std::cout << " -o, --output <file> Write output to file instead of stdout\n";
|
||||
std::cout << " -d, --definitions Print only symbol definitions\n";
|
||||
std::cout << " -s, --scopes Print only scope hierarchy\n";
|
||||
std::cout << " -r, --references Print only references\n";
|
||||
std::cout << " -i, --inheritance Print only inheritance graph\n";
|
||||
std::cout << " -c, --calls Print only call graph\n";
|
||||
std::cout << " -C, --compact Use compact output format\n";
|
||||
std::cout << " -S, --stats Print statistics only\n";
|
||||
std::cout << " -O, --overview Print overview only\n";
|
||||
@@ -193,21 +187,6 @@ bool ParseArguments(int argc, char* argv[], Options& options)
|
||||
options.print_scopes = true;
|
||||
any_specific_print = true;
|
||||
}
|
||||
else if (arg == "-r" || arg == "--references")
|
||||
{
|
||||
options.print_references = true;
|
||||
any_specific_print = true;
|
||||
}
|
||||
else if (arg == "-i" || arg == "--inheritance")
|
||||
{
|
||||
options.print_inheritance = true;
|
||||
any_specific_print = true;
|
||||
}
|
||||
else if (arg == "-c" || arg == "--calls")
|
||||
{
|
||||
options.print_calls = true;
|
||||
any_specific_print = true;
|
||||
}
|
||||
else if (arg == "-C" || arg == "--compact")
|
||||
{
|
||||
options.compact_mode = true;
|
||||
@@ -550,15 +529,6 @@ private:
|
||||
|
||||
EnterScope(symbol::ScopeKind::kClass, node.span, class_id);
|
||||
|
||||
for (const auto& parent : node.parent_classes)
|
||||
{
|
||||
auto it = name_index_.find(ToLower(parent.name));
|
||||
if (it != name_index_.end())
|
||||
{
|
||||
table_.AddInheritance(class_id, it->second);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& member : node.members)
|
||||
{
|
||||
if (member)
|
||||
@@ -1013,8 +983,6 @@ void AnalyzeFile(const Options& options)
|
||||
if (options.no_color || !options.output_file.empty())
|
||||
print_opts.use_color = false;
|
||||
|
||||
print_opts.show_references = options.print_references || options.verbose;
|
||||
|
||||
symbol::debug::DebugPrinter printer(table, print_opts);
|
||||
|
||||
if (!options.search_symbol.empty())
|
||||
@@ -1053,24 +1021,6 @@ void AnalyzeFile(const Options& options)
|
||||
printed_anything = true;
|
||||
}
|
||||
|
||||
if (options.print_references)
|
||||
{
|
||||
printer.PrintAllReferences(*out);
|
||||
printed_anything = true;
|
||||
}
|
||||
|
||||
if (options.print_inheritance)
|
||||
{
|
||||
printer.PrintAllInheritance(*out);
|
||||
printed_anything = true;
|
||||
}
|
||||
|
||||
if (options.print_calls)
|
||||
{
|
||||
printer.PrintAllCalls(*out);
|
||||
printed_anything = true;
|
||||
}
|
||||
|
||||
if (printed_anything)
|
||||
{
|
||||
*out << "\n";
|
||||
|
||||
Reference in New Issue
Block a user