From ddca9769e558e5b040b0812dfe9d38bd46b2c109 Mon Sep 17 00:00:00 2001 From: csh Date: Sat, 25 Oct 2025 14:02:55 +0800 Subject: [PATCH] refactor ast --- lsp-server/src/language/ast/cache.cpp | 101 - lsp-server/src/language/ast/cache.hpp | 94 - lsp-server/src/language/ast/deserializer.cpp | 1096 +------- lsp-server/src/language/ast/deserializer.hpp | 175 +- lsp-server/src/language/ast/detail.cpp | 2499 +++++++++++++++++ lsp-server/src/language/ast/detail.hpp | 206 ++ .../src/language/ast/token_collector.cpp | 312 ++ .../src/language/ast/token_collector.hpp | 153 + .../src/language/ast/tree_sitter_utils.cpp | 121 +- .../src/language/ast/tree_sitter_utils.hpp | 89 +- lsp-server/src/language/ast/types.hpp | 1413 ++++++++-- 11 files changed, 4419 insertions(+), 1840 deletions(-) delete mode 100644 lsp-server/src/language/ast/cache.cpp delete mode 100644 lsp-server/src/language/ast/cache.hpp create mode 100644 lsp-server/src/language/ast/detail.cpp create mode 100644 lsp-server/src/language/ast/detail.hpp create mode 100644 lsp-server/src/language/ast/token_collector.cpp create mode 100644 lsp-server/src/language/ast/token_collector.hpp diff --git a/lsp-server/src/language/ast/cache.cpp b/lsp-server/src/language/ast/cache.cpp deleted file mode 100644 index 45f6c4b..0000000 --- a/lsp-server/src/language/ast/cache.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include "./cache.hpp" -#include "./tree_sitter_utils.hpp" - -namespace lsp::language::ast -{ - NodeCache::NodeCache(size_t max_size) : - max_size_(max_size) - { - } - - const ASTNode* NodeCache::Find(const NodeKey& key) - { - auto it = cache_.find(key); - if (it != cache_.end()) - { - // 缓存命中,更新LRU - Touch(key, it->second.lru_iter); - ++hit_count_; - return &it->second.node; - } - - ++miss_count_; - return nullptr; - } - - void NodeCache::Insert(const NodeKey& key, const ASTNode& node) - { - auto it = cache_.find(key); - - if (it != cache_.end()) - { - // 键已存在,更新值和LRU - it->second.node = node; - Touch(key, it->second.lru_iter); - return; - } - - // 检查是否需要淘汰 - if (cache_.size() >= max_size_) - { - EvictLRU(); - } - - // 插入新条目 - lru_list_.push_front(key); - cache_[key] = CacheEntry{ node, lru_list_.begin() }; - } - - void NodeCache::Clear() - { - cache_.clear(); - lru_list_.clear(); - ResetStats(); - } - - void NodeCache::EvictLRU() - { - if (lru_list_.empty()) - return; - - // 移除最久未使用的(列表尾部) - const NodeKey& evict_key = lru_list_.back(); - cache_.erase(evict_key); - lru_list_.pop_back(); - } - - void NodeCache::Touch([[maybe_unused]] const NodeKey& key, KeyIter iter) - { - // 将元素移到列表前面(最近使用) - lru_list_.splice(lru_list_.begin(), lru_list_, iter); - } - - NodeKey NodeCache::MakeKey(const ASTNode& node) - { - return std::visit([](auto&& arg) -> NodeKey { - using T = std::decay_t; - if constexpr (std::is_same_v) - { - return NodeKey{ 0, 0, "" }; - } - else - { - return NodeKey{ - arg.location.start_byte, - arg.location.end_byte, - arg.node_type - }; - } - }, - node); - } - - NodeKey NodeCache::MakeKey(TSNode ts_node) - { - return NodeKey{ - ts_node_start_byte(ts_node), - ts_node_end_byte(ts_node), - std::string(ts::Type(ts_node)) - }; - } -} diff --git a/lsp-server/src/language/ast/cache.hpp b/lsp-server/src/language/ast/cache.hpp deleted file mode 100644 index 0c783be..0000000 --- a/lsp-server/src/language/ast/cache.hpp +++ /dev/null @@ -1,94 +0,0 @@ -#pragma once -#include -#include -#include -#include "./types.hpp" - -extern "C" { -#include -} - -namespace lsp::language::ast -{ - // ==================== 缓存键 ==================== - - struct NodeKey - { - uint32_t start_byte; - uint32_t end_byte; - std::string node_type; - - inline bool operator==(const NodeKey& other) const - { - return start_byte == other.start_byte && - end_byte == other.end_byte && - node_type == other.node_type; - } - }; - - struct NodeKeyHash - { - inline size_t operator()(const NodeKey& key) const - { - return std::hash()(key.start_byte) ^ - (std::hash()(key.end_byte) << 1) ^ - (std::hash()(key.node_type) << 2); - } - }; - - // ==================== LRU 缓存(重构 1)==================== - - class NodeCache - { - public: - explicit NodeCache(size_t max_size = 1000); - - const ASTNode* Find(const NodeKey& key); - void Insert(const NodeKey& key, const ASTNode& node); - void Clear(); - inline size_t Size() const { return cache_.size(); } - inline void SetMaxSize(size_t max_size) { max_size_ = max_size; } - inline size_t GetMaxSize() const { return max_size_; } - - // 缓存统计 - inline size_t HitCount() const { return hit_count_; } - inline size_t MissCount() const { return miss_count_; } - inline double HitRate() const - { - size_t total = hit_count_ + miss_count_; - return total > 0 ? static_cast(hit_count_) / total : 0.0; - } - - // 重置统计 - inline void ResetStats() - { - hit_count_ = 0; - miss_count_ = 0; - } - - static NodeKey MakeKey(const ASTNode& node); - static NodeKey MakeKey(TSNode ts_node); - - private: - // LRU 列表:最近使用的在前面 - using KeyList = std::list; - using KeyIter = KeyList::iterator; - - struct CacheEntry - { - ASTNode node; - KeyIter lru_iter; - }; - - void EvictLRU(); - void Touch(const NodeKey& key, KeyIter iter); - - size_t max_size_; - KeyList lru_list_; - std::unordered_map cache_; - - // 统计信息 - size_t hit_count_ = 0; - size_t miss_count_ = 0; - }; -} diff --git a/lsp-server/src/language/ast/deserializer.cpp b/lsp-server/src/language/ast/deserializer.cpp index f98a278..918cc2e 100644 --- a/lsp-server/src/language/ast/deserializer.cpp +++ b/lsp-server/src/language/ast/deserializer.cpp @@ -1,1075 +1,81 @@ -#include +#include "./detail.hpp" +#include "./tree_sitter_utils.hpp" #include "./deserializer.hpp" -extern "C" { -#include -} - namespace lsp::language::ast { // ==================== Deserializer 类实现 ==================== - Deserializer::Deserializer() : - cache_(std::make_unique()) + Deserializer::Deserializer() { + detail::RegisterStatementParsers(); } - Deserializer::~Deserializer() = default; - ParseResult Deserializer::Parse(TSNode root, const std::string& source) { - return ParseRoot(root, source); + ParseResult result; + + detail::ParseContext ctx(source, result.errors); + + uint32_t count = ts_node_child_count(root); + for (uint32_t i = 0; i < count; i++) + { + TSNode child = ts_node_child(root, i); + if (ts::IsComment(child)) + continue; + if (!ts_node_is_named(child)) + continue; + + StatementPtr stmt = detail::ParseStatement(child, ctx); + if (stmt) + result.statements.push_back(std::move(stmt)); + } + + // 收集语法错误 + auto syntax_errors = detail::CollectSyntaxErrors(root, source); + result.errors.insert(result.errors.end(), + std::make_move_iterator(syntax_errors.begin()), + std::make_move_iterator(syntax_errors.end())); + + return result; } IncrementalParseResult Deserializer::ParseIncremental(TSNode root, const std::string& source) { IncrementalParseResult result; - auto children = ts::Children(root); - for (const auto& child : children) + detail::ParseContext ctx(source, result.result.errors); + + uint32_t count = ts_node_child_count(root); + for (uint32_t i = 0; i < count; i++) { + TSNode child = ts_node_child(root, i); if (ts::IsComment(child)) continue; + if (!ts_node_is_named(child)) + continue; - ParseChildWithCache(child, source, result); + if (ts_node_has_changes(child)) + result.nodes_parsed++; + else + result.nodes_unchanged++; + + StatementPtr stmt = detail::ParseStatement(child, ctx); + if (stmt) + result.result.statements.push_back(std::move(stmt)); } + auto syntax_errors = detail::CollectSyntaxErrors(root, source); + result.result.errors.insert(result.result.errors.end(), + std::make_move_iterator(syntax_errors.begin()), + std::make_move_iterator(syntax_errors.end())); + return result; } - void Deserializer::ClearCache() + std::vector Deserializer::DiagnoseSyntax(TSNode root, const std::string& source) { - cache_->Clear(); + return detail::CollectSyntaxErrors(root, source); } - size_t Deserializer::CacheSize() const - { - return cache_->Size(); - } - - void Deserializer::SetCacheMaxSize(size_t max_size) - { - cache_->SetMaxSize(max_size); - } - - double Deserializer::CacheHitRate() const - { - return cache_->HitRate(); - } - - void Deserializer::ResetCacheStats() - { - cache_->ResetStats(); - } - - void Deserializer::ParseChildWithCache(TSNode child, const std::string& source, IncrementalParseResult& result) - { - if (ts_node_has_changes(child)) - { - // 节点有变化,重新解析 - auto parse_result = detail::ParseStatements(child, source); - - size_t base_idx = result.result.nodes.size(); - for (size_t i = 0; i < parse_result.nodes.size(); ++i) - { - auto& node = parse_result.nodes[i]; - NodeKey key = NodeCache::MakeKey(node); - cache_->Insert(key, node); - - result.result.nodes.push_back(std::move(node)); - result.changed_indices.push_back(base_idx + i); - } - - for (auto& error : parse_result.errors) - { - result.result.errors.push_back(std::move(error)); - } - } - else - { - // 节点未变化,尝试从缓存复用 - NodeKey key = NodeCache::MakeKey(child); - const ASTNode* cached = cache_->Find(key); - - if (cached) - { - size_t idx = result.result.nodes.size(); - result.result.nodes.push_back(*cached); - result.reused_indices.push_back(idx); - } - else - { - // 缓存未命中,需要解析 - auto parse_result = detail::ParseStatements(child, source); - - size_t base_idx = result.result.nodes.size(); - for (size_t i = 0; i < parse_result.nodes.size(); ++i) - { - auto& node = parse_result.nodes[i]; - NodeKey node_key = NodeCache::MakeKey(node); - cache_->Insert(node_key, node); - - result.result.nodes.push_back(std::move(node)); - result.changed_indices.push_back(base_idx + i); - } - - for (auto& error : parse_result.errors) - { - result.result.errors.push_back(std::move(error)); - } - } - } - } - - // ==================== Detail 函数实现 ==================== - - namespace detail - { - Result GetRequiredField(TSNode node, std::string_view field, const std::string& source, const std::string& error_msg) - { - std::string value = ts::FieldText(node, field, source); - if (value.empty()) - return Result::Err(error_msg); - return Result::Ok(std::move(value)); - } - - ParseError MakeError(TSNode node, const std::string& message, ErrorSeverity severity) - { - ParseError error; - error.location = ts::NodeLocation(node); - error.node_type = std::string(ts::Type(node)); - error.message = message; - error.severity = severity; - return error; - } - - Result ParseType(TSNode node, const std::string& source) - { - if (ts::IsNull(node)) - return Result::Err("Type node is null"); - - std::string name = ts::Text(node, source); - if (name.empty()) - return Result::Err("Type name is empty"); - - return Result::Ok(std::move(name)); - } - - Result ParseSignature(TSNode node, const std::string& source) - { - Signature sig; - - TSNode params_node = ts::FieldChild(node, "parameters"); - if (!ts::IsNull(params_node)) - { - auto params_result = ParseParameters(params_node, source); - if (params_result.IsErr()) - return Result::Err("Failed to extract parameters: " + params_result.error, - params_result.severity); - sig.parameters = std::move(params_result).Unwrap(); - } - - TSNode return_node = ts::FieldChild(node, "return_type"); - if (!ts::IsNull(return_node)) - { - auto type_result = ParseType(return_node, source); - if (type_result.IsOk()) - sig.return_type = std::move(type_result).Unwrap(); - } - - return Result::Ok(std::move(sig)); - } - - Result> ParseParameters(TSNode params_list_node, const std::string& source) - { - std::vector all_params; - auto param_nodes = ts::Children(params_list_node); - - for (const auto& param_node : param_nodes) - { - std::string node_type = std::string(ts::Type(param_node)); - if (node_type != "parameter") - continue; - - bool is_var = false; - bool is_out = false; - auto children = ts::Children(param_node); - for (const auto& child : children) - { - std::string text = ts::Text(child, source); - if (text == "var") - is_var = true; - if (text == "out") - is_out = true; - } - - std::optional type_name; - TSNode type_node = ts::FieldChild(param_node, "type"); - if (!ts::IsNull(type_node)) - { - auto type_result = ParseType(type_node, source); - if (type_result.IsOk()) - type_name = std::move(type_result).Unwrap(); - } - - std::optional default_value; - TSNode default_node = ts::FieldChild(param_node, "default"); - if (!ts::IsNull(default_node)) - default_value = ts::Text(default_node, source); - - auto names = ts::FieldSummaries(param_node, "name", source); - for (size_t i = 0; i < names.size(); i++) - { - Parameter param; - param.is_var = is_var; - param.is_out = is_out; - param.name = names[i].text; - param.type_name = type_name; - param.location = ts::NodeLocation(names[i].node); - param.name_location = ts::NodeLocation(names[i].node); - - if (i == names.size() - 1) - param.default_value = default_value; - - all_params.push_back(param); - } - } - - return Result>::Ok(std::move(all_params)); - } - - Result ParseBlock(TSNode node, const std::string& source) - { - if (ts::IsNull(node)) - return Result::Err("Block node is null"); - - Block block; - block.location = ts::NodeLocation(node); - block.node_type = std::string(ts::Type(node)); - - auto children = ts::Children(node); - auto parse_result = ParseChildren(children, source); - block.statements = std::move(parse_result.nodes); - - return Result::Ok(std::move(block)); - } - - Access ParseAccess(std::string_view text) - { - if (text == "protected") - return Access::kProtected; - if (text == "private") - return Access::kPrivate; - return Access::kPublic; - } - - // 重构 2:统一处理变量声明拆分 - ParseResult ParseStatements(TSNode node, const std::string& source) - { - ParseResult result; - std::string node_type = std::string(ts::Type(node)); - - // 处理需要拆分的变量声明 - if (node_type == "var_statement") - { - auto var_results = SplitVariableDeclaration( - node, source, ParseVarDeclaration); - - for (auto& var_result : var_results) - { - if (var_result.IsOk()) - { - result.nodes.push_back(std::move(var_result).Unwrap()); - } - else - { - result.errors.push_back(MakeError(node, var_result.error, var_result.severity)); - } - } - return result; - } - else if (node_type == "static_statement") - { - auto static_results = SplitVariableDeclaration( - node, source, ParseStaticDeclaration); - - for (auto& static_result : static_results) - { - if (static_result.IsOk()) - { - result.nodes.push_back(std::move(static_result).Unwrap()); - } - else - { - result.errors.push_back(MakeError(node, static_result.error, static_result.severity)); - } - } - return result; - } - else if (node_type == "global_statement") - { - auto global_results = SplitVariableDeclaration( - node, source, ParseGlobalDeclaration); - - for (auto& global_result : global_results) - { - if (global_result.IsOk()) - { - result.nodes.push_back(std::move(global_result).Unwrap()); - } - else - { - result.errors.push_back(MakeError(node, global_result.error, global_result.severity)); - } - } - return result; - } - - // 其他类型的声明不需要拆分 - auto parse_result = ParseNode(node, source); - if (parse_result.IsOk()) - { - result.nodes.push_back(std::move(parse_result).Unwrap()); - } - else - { - result.errors.push_back(MakeError(node, parse_result.error, parse_result.severity)); - } - - return result; - } - - ParseResult ParseChildren(const std::vector& children, const std::string& source) - { - ParseResult result; - - for (const auto& child : children) - { - if (ts::IsComment(child)) - continue; - - auto child_result = ParseStatements(child, source); - - for (auto& node : child_result.nodes) - { - result.nodes.push_back(std::move(node)); - } - - for (auto& error : child_result.errors) - { - result.errors.push_back(std::move(error)); - } - } - - return result; - } - - // 重构 4:拆分 ParseClassDefinition 的辅助函数 - void ParseClassMembers(TSNode body_node, const std::string& source, ClassDefinition& def) - { - Access current_access = Access::kPrivate; - auto children = ts::ChildSummaries(body_node, source); - - for (const auto& child : children) - { - if (child.type == "access_modifier") - { - current_access = ParseAccess(child.text); - } - else if (child.type == "variable_declaration") - { - ParseClassVariableMember(child.node, source, current_access, def); - } - else if (child.type == "method_declaration" || - child.type == "method_declaration_only" || - child.type == "method_with_modifier" || - child.type == "method_with_implementation") - { - ParseClassMethodMember(child.node, source, current_access, def); - } - else if (child.type == "property_declaration") - { - ParseClassPropertyMember(child.node, source, current_access, def); - } - } - } - - void ParseClassVariableMember(TSNode node, const std::string& source, Access current_access, ClassDefinition& def) - { - TSNode var_decl_node = ts::FieldChild(node, "variables"); - if (ts::IsNull(var_decl_node)) - return; - - std::string decl_type = std::string(ts::Type(var_decl_node)); - - if (decl_type == "static_declaration") - { - auto results = SplitVariableDeclaration( - var_decl_node, source, ParseStaticDeclaration); - - for (auto& result : results) - { - if (result.IsOk()) - { - ClassMember member; - member.access = current_access; - member.content = std::move(result).Unwrap(); - def.members.push_back(std::move(member)); - } - } - } - else if (decl_type == "nostatic_declaration") - { - auto results = SplitVariableDeclaration( - var_decl_node, source, ParseVarDeclaration); - - for (auto& result : results) - { - if (result.IsOk()) - { - ClassMember member; - member.access = current_access; - member.content = std::move(result).Unwrap(); - def.members.push_back(std::move(member)); - } - } - } - } - - void ParseClassMethodMember(TSNode node, const std::string& source, Access current_access, ClassDefinition& def) - { - auto result = ParseMethod(node, source); - if (result.IsOk()) - { - ClassMember member; - member.access = current_access; - member.content = std::move(result).Unwrap(); - def.members.push_back(std::move(member)); - } - } - - void ParseClassPropertyMember(TSNode node, const std::string& source, Access current_access, ClassDefinition& def) - { - auto result = ParseProperty(node, source); - if (result.IsOk()) - { - ClassMember member; - member.access = current_access; - member.content = std::move(result).Unwrap(); - def.members.push_back(std::move(member)); - } - } - - const std::unordered_map& GetParseFuncMap() - { - static const std::unordered_map parse_map = { - { "unit", [](TSNode node, const std::string& source) -> Result { - auto result = ParseUnitDefinition(node, source); - return result.IsOk() ? Result::Ok(std::move(result).Unwrap()) : Result::Err(result.error, result.severity); - } }, - { "function_definition_statement", [](TSNode node, const std::string& source) -> Result { - auto result = ParseFunctionDefinition(node, source); - return result.IsOk() ? Result::Ok(std::move(result).Unwrap()) : Result::Err(result.error, result.severity); - } }, - { "class_definition_statement", [](TSNode node, const std::string& source) -> Result { - auto result = ParseClassDefinition(node, source); - return result.IsOk() ? Result::Ok(std::move(result).Unwrap()) : Result::Err(result.error, result.severity); - } }, - { "const_statement", [](TSNode node, const std::string& source) -> Result { - auto result = ParseConstDeclaration(node, source); - return result.IsOk() ? Result::Ok(std::move(result).Unwrap()) : Result::Err(result.error, result.severity); - } }, - { "assignment_statement", [](TSNode node, const std::string& source) -> Result { - auto result = ParseAssignmentStatement(node, source); - return result.IsOk() ? Result::Ok(std::move(result).Unwrap()) : Result::Err(result.error, result.severity); - } }, - { "uses_statement", [](TSNode node, const std::string& source) -> Result { - auto result = ParseUsesClause(node, source); - return result.IsOk() ? Result::Ok(std::move(result).Unwrap()) : Result::Err(result.error, result.severity); - } }, - { "external_method_statement", [](TSNode node, const std::string& source) -> Result { - auto result = ParseExternalMethod(node, source); - return result.IsOk() ? Result::Ok(std::move(result).Unwrap()) : Result::Err(result.error, result.severity); - } }, - { "function_definition_statement_with_overload", [](TSNode node, const std::string& source) -> Result { - auto result = ParseFunctionDefinition(node, source); - return result.IsOk() ? Result::Ok(std::move(result).Unwrap()) : Result::Err(result.error, result.severity); - } } - }; - return parse_map; - } - } - - // ==================== 具体类型解析函数 ==================== - - Result ParseFunctionDefinition(TSNode node, const std::string& source) - { - std::string node_type = std::string(ts::Type(node)); - if (node_type != "function_definition_statement" && node_type != "function_definition_statement_with_overload") - return Result::Err("Not a function definition"); - - FunctionDefinition def; - detail::InitNode(def, node); - - if (node_type == "function_definition_statement_with_overload") - def.is_overload = true; - - if (!detail::ExtractNameAndLocation(def, node, source)) - return Result::Err("Function missing name"); - - auto sig_result = detail::ParseSignature(node, source); - if (sig_result.IsErr()) - return Result::Err("Failed to extract signature: " + sig_result.error, - sig_result.severity); - def.signature = std::move(sig_result).Unwrap(); - - TSNode body_node = ts::FieldChild(node, "body"); - if (!ts::IsNull(body_node)) - { - auto block_result = detail::ParseBlock(body_node, source); - if (block_result.IsErr()) - return Result::Err("Failed to extract body: " + block_result.error, block_result.severity); - def.body = std::move(block_result).Unwrap(); - } - - return Result::Ok(std::move(def)); - } - - Result ParseClassDefinition(TSNode node, const std::string& source) - { - std::string node_type = std::string(ts::Type(node)); - if (node_type != "class_definition_statement") - return Result::Err("Not a class definition"); - - ClassDefinition def; - detail::InitNode(def, node); - - if (!detail::ExtractNameAndLocation(def, node, source)) - return Result::Err("Class missing name"); - - // 提取父类 - auto parent_summaries = ts::FieldSummaries(node, "parent", source); - for (const auto& parent : parent_summaries) - { - def.parents.push_back(parent.text); - } - - // 提取类体(重构 4:使用拆分的辅助函数) - TSNode body_node = ts::FieldChild(node, "body"); - if (!ts::IsNull(body_node)) - { - detail::ParseClassMembers(body_node, source, def); - } - - return Result::Ok(std::move(def)); - } - - Result ParseMethod(TSNode node, const std::string& source) - { - std::string node_type = std::string(ts::Type(node)); - if (node_type != "method_declaration" && - node_type != "method_declaration_only" && - node_type != "method_with_modifier" && - node_type != "method_with_implementation") - return Result::Err("Not a method declaration"); - - Method method; - detail::InitNode(method, node); - - auto children = ts::Children(node); - for (const auto& child : children) - { - if (std::string(ts::Type(child)) == "class") - { - method.is_class_method = true; - break; - } - } - - TSNode name_node = ts::FieldChild(node, "name"); - if (!ts::IsNull(name_node)) - { - std::string name_type = std::string(ts::Type(name_node)); - if (name_type == "operator_overload") - { - TSNode op_node = ts::FieldChild(name_node, "operator"); - if (!ts::IsNull(op_node)) - { - method.name = "operator" + ts::Text(op_node, source); - method.name_location = ts::NodeLocation(op_node); - } - } - else - { - method.name = ts::Text(name_node, source); - method.name_location = ts::NodeLocation(name_node); - } - } - - if (method.name.empty()) - return Result::Err("Method missing name"); - - auto sig_result = detail::ParseSignature(node, source); - if (sig_result.IsErr()) - return Result::Err("Failed to extract signature: " + sig_result.error, sig_result.severity); - method.signature = std::move(sig_result).Unwrap(); - - TSNode modifier_node = ts::FieldChild(node, "modifier"); - if (!ts::IsNull(modifier_node)) - { - std::string modifier_text = ts::Text(modifier_node, source); - if (modifier_text == "virtual") - method.modifier = Modifier::kVirtual; - else if (modifier_text == "override") - method.modifier = Modifier::kOverride; - else if (modifier_text == "overload") - method.modifier = Modifier::kOverload; - } - - TSNode body_node = ts::FieldChild(node, "body"); - if (!ts::IsNull(body_node)) - { - auto block_result = detail::ParseBlock(body_node, source); - if (block_result.IsErr()) - return Result::Err("Failed to extract body: " + block_result.error, block_result.severity); - method.body = std::move(block_result).Unwrap(); - } - - return Result::Ok(std::move(method)); - } - - Result ParseExternalMethod(TSNode node, const std::string& source) - { - std::string node_type = std::string(ts::Type(node)); - - if (node_type == "external_method_statement") - { - auto result = ParseExternalMethod(ts::Children(node)[0], source); - return result.IsOk() ? Result::Ok(std::move(result).Unwrap()) : Result::Err(result.error, result.severity); - } - - // 检查节点类型 - bool is_modifier = (node_type == "modifier_method"); - bool is_operator = (node_type == "operator_method"); - bool is_normal = (node_type == "normal_method"); - - if (!is_modifier && !is_operator && !is_normal) - return Result::Err("Not an external method"); - - ExternalMethod method; - detail::InitNode(method, node); - method.is_operator = is_operator; - - // 提取类名 - TSNode class_name_node = ts::FieldChild(node, "class_name"); - if (ts::IsNull(class_name_node)) - return Result::Err("External method missing class name"); - method.class_name = ts::Text(class_name_node, source); - - // 提取方法名或运算符 - if (is_operator) - { - TSNode op_node = ts::FieldChild(node, "operator"); - if (!ts::IsNull(op_node)) - { - method.operator_symbol = ts::Text(op_node, source); - method.method_name = "operator" + method.operator_symbol; - method.name_location = ts::NodeLocation(op_node); - } - } - else - { - TSNode method_name_node = ts::FieldChild(node, "method_name"); - if (ts::IsNull(method_name_node)) - return Result::Err("External method missing method name"); - method.method_name = ts::Text(method_name_node, source); - method.name_location = ts::NodeLocation(method_name_node); - } - - if (method.method_name.empty()) - return Result::Err("Method name is empty"); - - // 检查是否是 class method - auto children = ts::Children(node); - for (const auto& child : children) - { - if (std::string(ts::Type(child)) == "class") - { - method.is_class_method = true; - break; - } - } - - // 提取签名 - auto sig_result = detail::ParseSignature(node, source); - if (sig_result.IsErr()) - return Result::Err("Failed to extract signature: " + sig_result.error, - sig_result.severity); - method.signature = std::move(sig_result).Unwrap(); - - // 提取修饰符(如果有) - TSNode modifier_node = ts::FieldChild(node, "modifier"); - if (!ts::IsNull(modifier_node)) - { - std::string modifier_text = ts::Text(modifier_node, source); - if (modifier_text == "virtual") - method.modifier = Modifier::kVirtual; - else if (modifier_text == "override") - method.modifier = Modifier::kOverride; - else if (modifier_text == "overload") - method.modifier = Modifier::kOverload; - } - - // 提取方法体 - TSNode body_node = ts::FieldChild(node, "body"); - if (!ts::IsNull(body_node)) - { - auto block_result = detail::ParseBlock(body_node, source); - if (block_result.IsErr()) - return Result::Err("Failed to extract body: " + block_result.error, - block_result.severity); - method.body = std::move(block_result).Unwrap(); - } - else - { - return Result::Err("External method missing body"); - } - - return Result::Ok(std::move(method)); - } - - Result ParseProperty(TSNode node, const std::string& source) - { - std::string node_type = std::string(ts::Type(node)); - if (node_type != "property_declaration") - return Result::Err("Not a property declaration"); - - Property prop; - detail::InitNode(prop, node); - - if (!detail::ExtractNameAndLocation(prop, node, source)) - return Result::Err("Property missing name"); - - TSNode type_node = ts::FieldChild(node, "type"); - if (!ts::IsNull(type_node)) - { - auto type_result = detail::ParseType(type_node, source); - if (type_result.IsOk()) - prop.type_name = std::move(type_result).Unwrap(); - } - - TSNode accessors_node = ts::FieldChild(node, "accessors"); - if (!ts::IsNull(accessors_node)) - { - std::string accessor_type = std::string(ts::Type(accessors_node)); - - if (accessor_type == "read_only_accessor" || - accessor_type == "read_write_accessor" || - accessor_type == "write_read_accessor") - { - auto children = ts::ChildSummaries(accessors_node, source); - for (size_t i = 0; i < children.size(); i++) - { - if (children[i].text == "read" && i + 1 < children.size()) - { - prop.getter = children[i + 1].text; - } - else if (children[i].text == "write" && i + 1 < children.size()) - { - prop.setter = children[i + 1].text; - } - } - } - else if (accessor_type == "write_only_accessor") - { - auto children = ts::ChildSummaries(accessors_node, source); - for (size_t i = 0; i < children.size(); i++) - { - if (children[i].text == "write" && i + 1 < children.size()) - { - prop.setter = children[i + 1].text; - } - } - } - } - - return Result::Ok(std::move(prop)); - } - - Result ParseVarDeclaration(TSNode node, const std::string& source, const std::string& var_name, TSNode name_node) - { - std::string node_type = std::string(ts::Type(node)); - if (node_type != "var_statement" && - node_type != "var_declaration" && - node_type != "nostatic_declaration") - return Result::Err("Not a var statement"); - - VarDeclaration var; - var.location = ts::NodeLocation(name_node); - var.node_type = node_type; - var.name = var_name; - var.name_location = ts::NodeLocation(name_node); - - TSNode type_node = ts::FieldChild(node, "type"); - if (!ts::IsNull(type_node)) - { - auto type_result = detail::ParseType(type_node, source); - if (type_result.IsOk()) - var.type_name = std::move(type_result).Unwrap(); - } - - TSNode value_node = ts::FieldChild(node, "value"); - if (!ts::IsNull(value_node)) - { - Expression expr; - expr.location = ts::NodeLocation(value_node); - expr.node_type = std::string(ts::Type(value_node)); - expr.text = ts::Text(value_node, source); - var.value = std::move(expr); - } - - return Result::Ok(std::move(var)); - } - - Result ParseStaticDeclaration(TSNode node, const std::string& source, const std::string& var_name, TSNode name_node) - { - std::string node_type = std::string(ts::Type(node)); - if (node_type != "static_statement" && node_type != "static_declaration") - return Result::Err("Not a static statement"); - - StaticDeclaration decl; - decl.location = ts::NodeLocation(name_node); - decl.node_type = node_type; - decl.name = var_name; - decl.name_location = ts::NodeLocation(name_node); - - TSNode type_node = ts::FieldChild(node, "type"); - if (!ts::IsNull(type_node)) - { - auto type_result = detail::ParseType(type_node, source); - if (type_result.IsOk()) - decl.type_name = std::move(type_result).Unwrap(); - } - - TSNode value_node = ts::FieldChild(node, "value"); - if (!ts::IsNull(value_node)) - { - Expression expr; - expr.location = ts::NodeLocation(value_node); - expr.node_type = std::string(ts::Type(value_node)); - expr.text = ts::Text(value_node, source); - decl.value = std::move(expr); - } - - return Result::Ok(std::move(decl)); - } - - Result ParseGlobalDeclaration(TSNode node, const std::string& source, const std::string& var_name, TSNode name_node) - { - std::string node_type = std::string(ts::Type(node)); - if (node_type != "global_statement" && node_type != "global_declaration") - return Result::Err("Not a global statement"); - - GlobalDeclaration decl; - decl.location = ts::NodeLocation(name_node); - decl.node_type = node_type; - decl.name = var_name; - decl.name_location = ts::NodeLocation(name_node); - - TSNode type_node = ts::FieldChild(node, "type"); - if (!ts::IsNull(type_node)) - { - auto type_result = detail::ParseType(type_node, source); - if (type_result.IsOk()) - decl.type_name = std::move(type_result).Unwrap(); - } - - TSNode value_node = ts::FieldChild(node, "value"); - if (!ts::IsNull(value_node)) - { - Expression expr; - expr.location = ts::NodeLocation(value_node); - expr.node_type = std::string(ts::Type(value_node)); - expr.text = ts::Text(value_node, source); - decl.value = std::move(expr); - } - - return Result::Ok(std::move(decl)); - } - - Result ParseConstDeclaration(TSNode node, const std::string& source) - { - std::string node_type = std::string(ts::Type(node)); - if (node_type != "const_statement") - return Result::Err("Not a const statement"); - - ConstDeclaration const_decl; - detail::InitNode(const_decl, node); - - if (!detail::ExtractNameAndLocation(const_decl, node, source)) - return Result::Err("Const missing name"); - - TSNode type_node = ts::FieldChild(node, "type"); - if (!ts::IsNull(type_node)) - { - auto type_result = detail::ParseType(type_node, source); - if (type_result.IsOk()) - const_decl.type_name = std::move(type_result).Unwrap(); - } - - TSNode value_node = ts::FieldChild(node, "value"); - if (ts::IsNull(value_node)) - { - return Result::Err("Const declaration missing value"); - } - const_decl.value.location = ts::NodeLocation(value_node); - const_decl.value.node_type = std::string(ts::Type(value_node)); - const_decl.value.text = ts::Text(value_node, source); - - return Result::Ok(std::move(const_decl)); - } - - Result ParseAssignmentStatement(TSNode node, const std::string& source) - { - std::string node_type = std::string(ts::Type(node)); - if (node_type != "assignment_statement") - return Result::Err("Not an assignment statement"); - - AssignmentStatement var; - detail::InitNode(var, node); - - TSNode left_node = ts::FieldChild(node, "left"); - if (ts::IsNull(left_node)) - return Result::Err("Assignment missing left side"); - - var.name = ts::Text(left_node, source); - var.name_location = ts::NodeLocation(left_node); - if (var.name.empty()) - return Result::Err("Assignment left side is empty"); - - TSNode right_node = ts::FieldChild(node, "right"); - if (!ts::IsNull(right_node)) - { - var.value.location = ts::NodeLocation(right_node); - var.value.node_type = std::string(ts::Type(right_node)); - var.value.text = ts::Text(right_node, source); - } - - return Result::Ok(std::move(var)); - } - - Result ParseUnitDefinition(TSNode node, const std::string& source) - { - std::string node_type = std::string(ts::Type(node)); - if (node_type != "unit") - return Result::Err("Not a unit"); - - UnitDefinition unit; - detail::InitNode(unit, node); - - if (!detail::ExtractNameAndLocation(unit, node, source)) - return Result::Err("Unit missing name"); - - TSNode uses_node = ts::FieldChild(node, "uses"); - if (!ts::IsNull(uses_node)) - { - auto uses_result = ParseUsesClause(uses_node, source); - if (uses_result.IsOk()) - unit.uses = std::move(uses_result).Unwrap(); - } - - TSNode interface_node = ts::FieldChild(node, "interface"); - if (!ts::IsNull(interface_node)) - { - auto children = ts::Children(interface_node); - auto parse_result = detail::ParseChildren(children, source); - unit.interface_statements = std::move(parse_result.nodes); - } - - TSNode impl_node = ts::FieldChild(node, "implementation"); - if (!ts::IsNull(impl_node)) - { - auto children = ts::Children(impl_node); - auto parse_result = detail::ParseChildren(children, source); - unit.implementation_statements = std::move(parse_result.nodes); - } - - TSNode init_node = ts::FieldChild(node, "initialization"); - if (!ts::IsNull(init_node)) - { - auto children = ts::Children(init_node); - auto parse_result = detail::ParseChildren(children, source); - unit.initialization_statements = std::move(parse_result.nodes); - } - - TSNode final_node = ts::FieldChild(node, "finalization"); - if (!ts::IsNull(final_node)) - { - auto children = ts::Children(final_node); - auto parse_result = detail::ParseChildren(children, source); - unit.finalization_statements = std::move(parse_result.nodes); - } - - return Result::Ok(std::move(unit)); - } - - Result ParseUsesClause(TSNode node, const std::string& source) - { - std::string node_type = std::string(ts::Type(node)); - if (node_type != "uses_statement") - return Result::Err("Not a uses statement"); - - UsesClause uses; - detail::InitNode(uses, node); - - auto modules = ts::FieldSummaries(node, "module", source); - for (const auto& module : modules) - uses.units.push_back(module.text); - - return Result::Ok(std::move(uses)); - } - - // ==================== 顶层 API ==================== - - Result ParseNode(TSNode node, const std::string& source) - { - std::string node_type = std::string(ts::Type(node)); - - // 重构 3:使用函数映射表 - const auto& parse_map = detail::GetParseFuncMap(); - auto it = parse_map.find(node_type); - - if (it != parse_map.end()) - { - return it->second(node, source); - } - - return Result::Err("Unknown node type: " + node_type, ErrorSeverity::Warning); - } - - ParseResult ParseRoot(TSNode root, const std::string& source) - { - ParseResult result; - auto children = ts::Children(root); - - for (const auto& child : children) - { - if (ts::IsComment(child)) - continue; - - auto parse_result = detail::ParseStatements(child, source); - - for (auto& node : parse_result.nodes) - { - result.nodes.push_back(std::move(node)); - } - - for (auto& error : parse_result.errors) - { - result.errors.push_back(std::move(error)); - } - } - - return result; - } } diff --git a/lsp-server/src/language/ast/deserializer.hpp b/lsp-server/src/language/ast/deserializer.hpp index 5641ae2..46d0103 100644 --- a/lsp-server/src/language/ast/deserializer.hpp +++ b/lsp-server/src/language/ast/deserializer.hpp @@ -1,133 +1,86 @@ #pragma once -#include -#include -#include + +#include #include "./types.hpp" -#include "./tree_sitter_utils.hpp" -#include "./cache.hpp" + +extern "C" { +#include +} namespace lsp::language::ast { - // ==================== 增量解析结果 ==================== - - struct IncrementalParseResult + // ===== 解析错误 ===== + enum class ErrorSeverity { - ParseResult result; - std::vector changed_indices; - std::vector reused_indices; + Warning, + Error, + Fatal + }; - inline size_t ChangedCount() const { return changed_indices.size(); } - inline size_t ReusedCount() const { return reused_indices.size(); } - inline size_t TotalCount() const { return result.nodes.size(); } - inline double ReuseRate() const + struct ParseError + { + Location location; + std::string node_type; + std::string message; + ErrorSeverity severity = ErrorSeverity::Error; + + static ParseError Create(const Location& loc, const std::string& type, const std::string& msg) { - return TotalCount() > 0 ? static_cast(ReusedCount()) / TotalCount() : 0.0; + return { loc, type, msg, ErrorSeverity::Error }; + } + + static ParseError Missing(const Location& loc, const std::string& type) + { + return Create(loc, type, "Syntax error: missing " + type); + } + + static ParseError Unexpected(const Location& loc, const std::string& type, const std::string& context = "") + { + std::string msg = "Syntax error: unexpected token"; + if (!context.empty()) + msg += " in " + context; + return Create(loc, type, msg); } }; + // ===== 解析结果 ===== + struct ParseResult + { + std::vector statements; + std::vector errors; + + bool HasErrors() const { return !errors.empty(); } + bool IsSuccess() const { return errors.empty(); } + size_t ErrorCount() const { return errors.size(); } + }; + + // ===== 增量解析结果 ===== + struct IncrementalParseResult + { + ParseResult result; + size_t nodes_parsed = 0; // 重新解析的节点数 + size_t nodes_unchanged = 0; // 未变化的节点数 + + size_t TotalNodes() const { return nodes_parsed + nodes_unchanged; } + double ChangeRate() const + { + return TotalNodes() > 0 ? static_cast(nodes_parsed) / TotalNodes() : 0.0; + } + }; + + // ===== Deserializer 类 ===== class Deserializer { public: Deserializer(); - ~Deserializer(); + ~Deserializer() = default; + Deserializer(const Deserializer&) = delete; + Deserializer& operator=(const Deserializer&) = delete; - // 基础解析(不使用缓存) ParseResult Parse(TSNode root, const std::string& source); - - // 增量解析(自动复用缓存) IncrementalParseResult ParseIncremental(TSNode root, const std::string& source); - // 缓存管理 - void ClearCache(); - size_t CacheSize() const; - void SetCacheMaxSize(size_t max_size); - - // 缓存统计 - double CacheHitRate() const; - void ResetCacheStats(); - - private: - std::unique_ptr cache_; - - void ParseChildWithCache(TSNode child, const std::string& source, IncrementalParseResult& result); + static std::vector DiagnoseSyntax(TSNode root, const std::string& source); }; - namespace detail - { - using ParseFunc = std::function(TSNode, const std::string&)>; - - // 获取解析函数映射表 - const std::unordered_map& GetParseFuncMap(); - - // 辅助函数 - template - inline void InitNode(T& node, TSNode ts_node) - { - node.location = ts::NodeLocation(ts_node); - node.node_type = std::string(ts::Type(ts_node)); - } - - template - inline bool ExtractNameAndLocation(T& node, TSNode ts_node, const std::string& source) - { - TSNode name_node = ts::FieldChild(ts_node, "name"); - if (ts::IsNull(name_node)) - return false; - - node.name = ts::Text(name_node, source); - node.name_location = ts::NodeLocation(name_node); - return !node.name.empty(); - } - - Result GetRequiredField(TSNode node, std::string_view field, const std::string& source, const std::string& error_msg); - Result ParseType(TSNode node, const std::string& source); - Result ParseSignature(TSNode node, const std::string& source); - Result> ParseParameters(TSNode node, const std::string& source); - Result ParseBlock(TSNode node, const std::string& source); - Access ParseAccess(std::string_view text); - ParseError MakeError(TSNode node, const std::string& message, ErrorSeverity severity = ErrorSeverity::Error); - - template - inline std::vector> SplitVariableDeclaration( - TSNode node, - const std::string& source, - std::function(TSNode, const std::string&, const std::string&, TSNode)> parse_func) - { - std::vector> results; - auto names = ts::FieldSummaries(node, "name", source); - for (const auto& name_summary : names) - { - results.push_back(parse_func(node, source, name_summary.text, name_summary.node)); - } - return results; - } - - void ParseClassMembers(TSNode body_node, const std::string& source, ClassDefinition& def); - void ParseClassVariableMember(TSNode node, const std::string& source, Access current_access, ClassDefinition& def); - void ParseClassMethodMember(TSNode node, const std::string& source, Access current_access, ClassDefinition& def); - void ParseClassPropertyMember(TSNode node, const std::string& source, Access current_access, ClassDefinition& def); - - ParseResult ParseStatements(TSNode node, const std::string& source); - ParseResult ParseChildren(const std::vector& children, const std::string& source); - } - - // ==================== 顶层解析 API ==================== - - Result ParseNode(TSNode node, const std::string& source); - ParseResult ParseRoot(TSNode root, const std::string& source); - - // ==================== 具体类型解析函数 ==================== - - Result ParseVarDeclaration(TSNode node, const std::string& source, const std::string& var_name, TSNode name_node); - Result ParseStaticDeclaration(TSNode node, const std::string& source, const std::string& var_name, TSNode name_node); - Result ParseGlobalDeclaration(TSNode node, const std::string& source, const std::string& var_name, TSNode name_node); - Result ParseConstDeclaration(TSNode node, const std::string& source); - Result ParseAssignmentStatement(TSNode node, const std::string& source); - Result ParseFunctionDefinition(TSNode node, const std::string& source); - Result ParseClassDefinition(TSNode node, const std::string& source); - Result ParseMethod(TSNode node, const std::string& source); - Result ParseExternalMethod(TSNode node, const std::string& source); - Result ParseProperty(TSNode node, const std::string& source); - Result ParseUnitDefinition(TSNode node, const std::string& source); - Result ParseUsesClause(TSNode node, const std::string& source); } diff --git a/lsp-server/src/language/ast/detail.cpp b/lsp-server/src/language/ast/detail.cpp new file mode 100644 index 0000000..c3c7dee --- /dev/null +++ b/lsp-server/src/language/ast/detail.cpp @@ -0,0 +1,2499 @@ +#include +#include +#include "../../utils/string.hpp" +#include "./tree_sitter_utils.hpp" +#include "./detail.hpp" + +namespace lsp::language::ast::detail +{ + void RegisterStatementParsers() + { + static std::once_flag once; + std::call_once(once, [] { + auto& registry = StatementParserRegistry::Instance(); + + // 直接注册,不需要适配器 + registry.Register("unit", ParseUnitDefinition); + registry.Register("var_statement", ParseVarStatement); + registry.Register("static_statement", ParseStaticStatement); + registry.Register("global_statement", ParseGlobalStatement); + registry.Register("const_statement", ParseConstStatement); + registry.Register("assignment_statement", ParseAssignmentStatement); + registry.Register("expression_statement", ParseExpressionStatement); + registry.Register("break_statement", ParseBreakStatement); + registry.Register("continue_statement", ParseContinueStatement); + registry.Register("return_statement", ParseReturnStatement); + registry.Register("uses_statement", ParseUsesStatement); + registry.Register("inherited_statement", ParseInheritedStatement); + registry.Register("single_suite", ParseSingleSuite); + registry.Register("block_suite", ParseBlockSuite); + registry.Register("if_statement", ParseIfStatement); + registry.Register("for_in_statement", ParseForInStatement); + registry.Register("for_to_statement", ParseForToStatement); + registry.Register("while_statement", ParseWhileStatement); + registry.Register("repeat_statement", ParseRepeatStatement); + registry.Register("case_statement", ParseCaseStatement); + registry.Register("try_statement", ParseTryStatement); + registry.Register("function_declaration_statement", ParseFunctionDeclaration); + registry.Register("function_definition_statement", ParseFunctionDefinition); + registry.Register("function_definition_with_overload_statement", ParseFunctionDefinition); + registry.Register("class_definition_statement", ParseClassDefinition); + registry.Register("external_method_statement", ParseExternalMethodStatement); + registry.Register("matrix_iteration_statement", ParseMatrixIterationStatement); + + registry.Register("anonymous_function_statement", + [](TSNode n, ParseContext& ctx) -> StatementPtr { + auto expr = ParseAnonymousFunctionExpression(n, ctx); + if (!expr) + return nullptr; + Location loc = ts::NodeLocation(n); + auto stmt = MakeNode(); + stmt->kind = NodeKind::kExpressionStatement; + stmt->location = loc; + stmt->node_type_name = "expression_statement"; + stmt->expression = std::move(expr); + return stmt; + }); + + registry.Register("tslx_open_tag", ParseTSLXOpenTag); + registry.Register("tslx_close_tag", ParseTSLXCloseTag); + registry.Register("tslx_output_tag", ParseTSLXOutputTag); + registry.Register("tslx_expression_tag", ParseTSLXExpressionTag); + registry.Register("html_self_closing_tag", ParseHTMLSelfClosingTag); + registry.Register("html_paired_tag", ParseHTMLPairedTag); + registry.Register("html_comment", ParseHTMLComment); + }); + } + + BinaryOperator ParseBinaryOperator(const std::string& op_text) + { + static const std::unordered_map op_map = { + // Arithmetic + { "+", BinaryOperator::kAdd }, + { "-", BinaryOperator::kSubtract }, + { "*", BinaryOperator::kMultiply }, + { "/", BinaryOperator::kDivide }, + { "\\", BinaryOperator::kIntDivide }, + { "%", BinaryOperator::kModulo }, + { "mod", BinaryOperator::kModulo }, + { "div", BinaryOperator::kIntDivide }, + { "^", BinaryOperator::kPower }, + { "~", BinaryOperator::kLogarithm }, + + // Comparison + { "=", BinaryOperator::kEqual }, + { "<>", BinaryOperator::kNotEqual }, + { ">", BinaryOperator::kGreater }, + { ">=", BinaryOperator::kGreaterEqual }, + { "<", BinaryOperator::kLess }, + { "<=", BinaryOperator::kLessEqual }, + { ".=", BinaryOperator::kDotEqual }, + { ".<>", BinaryOperator::kDotNotEqual }, + { ".>", BinaryOperator::kDotGreater }, + { ".>=", BinaryOperator::kDotGreaterEqual }, + { ".<", BinaryOperator::kDotLess }, + { ".<=", BinaryOperator::kDotLessEqual }, + { "like", BinaryOperator::kLike }, + { "is", BinaryOperator::kIs }, + { "in", BinaryOperator::kIn }, + + // Logical + { "or", BinaryOperator::kLogicalOr }, + { "and", BinaryOperator::kLogicalAnd }, + { ".||", BinaryOperator::kDotLogicalOr }, + { "||", BinaryOperator::kDotLogicalOr }, + { ".&&", BinaryOperator::kDotLogicalAnd }, + { "&&", BinaryOperator::kDotLogicalAnd }, + + // Bitwise + { ".|", BinaryOperator::kBitwiseOr }, + { ".&", BinaryOperator::kBitwiseAnd }, + { ".^", BinaryOperator::kBitwiseXor }, + { "shl", BinaryOperator::kShl }, + { "shr", BinaryOperator::kShr }, + { "rol", BinaryOperator::kRol }, + { "ror", BinaryOperator::kRor }, + + // Matrix + { ":*", BinaryOperator::kMatrixMultiply }, + { ":/", BinaryOperator::kMatrixDivide }, + { ":\\", BinaryOperator::kMatrixIntDivide }, + { ":^", BinaryOperator::kMatrixPower }, + { ":|", BinaryOperator::kMatrixConcat }, + { "|", BinaryOperator::kMatrixConcatVertical }, + + // Set + { "union", BinaryOperator::kUnion }, + { "union2", BinaryOperator::kUnion2 }, + { "intersect", BinaryOperator::kIntersect }, + { "outersect", BinaryOperator::kOutersect }, + { "minus", BinaryOperator::kMinus }, + + // Other + { "$", BinaryOperator::kConcatenation }, + { "->", BinaryOperator::kRange }, + }; + + auto it = op_map.find(op_text); + if (it != op_map.end()) + return it->second; + + return BinaryOperator::kAdd; // 默认值 + } + + UnaryOperator ParseUnaryOperator(const std::string& op_text) + { + static const std::unordered_map op_map = { + { "+", UnaryOperator::kPlus }, + { "-", UnaryOperator::kMinus }, + { "not", UnaryOperator::kNot }, + { ".!", UnaryOperator::kBitwiseNot }, + { ".!!", UnaryOperator::kDotNot }, + { "`", UnaryOperator::kMatrixTranspose }, + { "!", UnaryOperator::kDerivative }, + { "@", UnaryOperator::kExprAt }, + { "&", UnaryOperator::kExprRef }, + }; + + auto it = op_map.find(op_text); + return it != op_map.end() ? it->second : UnaryOperator::kPlus; + } + + AssignmentOperator ParseAssignmentOperator(const std::string& op_text) + { + static const std::unordered_map op_map = { + { ":=", AssignmentOperator::kAssign }, + { "+=", AssignmentOperator::kAddAssign }, + { "-=", AssignmentOperator::kSubtractAssign }, + { "*=", AssignmentOperator::kMultiplyAssign }, + { "/=", AssignmentOperator::kDivideAssign }, + { "\\=", AssignmentOperator::kIntDivideAssign }, + { "^=", AssignmentOperator::kPowerAssign }, + { "~=", AssignmentOperator::kLogarithmAssign }, + { "%=", AssignmentOperator::kModuloAssign }, + { "div=", AssignmentOperator::kDivAssign }, + { "|=", AssignmentOperator::kBitwiseOrAssign }, + { "&=", AssignmentOperator::kBitwiseAndAssign }, + { ":*=", AssignmentOperator::kMatrixMultiplyAssign }, + { ":/=", AssignmentOperator::kMatrixDivideAssign }, + { ":\\=", AssignmentOperator::kMatrixIntDivideAssign }, + { ":^=", AssignmentOperator::kMatrixPowerAssign }, + { ":|=", AssignmentOperator::kMatrixConcatAssign }, + { "::=", AssignmentOperator::kConcatAssign }, + { ".|=", AssignmentOperator::kDotBitwiseOrAssign }, + { ".&=", AssignmentOperator::kDotBitwiseAndAssign }, + { ".||=", AssignmentOperator::kDotLogicalOrAssign }, + { ".&&=", AssignmentOperator::kDotLogicalAndAssign }, + { ".^=", AssignmentOperator::kDotBitwiseXorAssign }, + { "union=", AssignmentOperator::kUnionAssign }, + { "union2=", AssignmentOperator::kUnion2Assign }, + { "intersect=", AssignmentOperator::kIntersectAssign }, + { "outersect=", AssignmentOperator::kOutersectAssign }, + { "minus=", AssignmentOperator::kMinusAssign }, + }; + + auto it = op_map.find(op_text); + return it != op_map.end() ? it->second : AssignmentOperator::kAssign; + } + + // ===== 基础辅助函数 ===== + + bool IsSyntaxErrorNode(TSNode node) + { + if (ts_node_is_error(node)) + return true; + + std::string_view type = ts_node_type(node); + return type == "ERROR" || type == "MISSING"; + } + + std::vector CollectSyntaxErrors(TSNode node, const std::string& source) + { + std::vector errors; + + if (IsSyntaxErrorNode(node)) + { + Location loc = ts::NodeLocation(node); + std::string type = ts_node_type(node); + + if (ts_node_is_missing(node)) + { + errors.push_back(ParseError::Missing(loc, type)); + } + else + { + std::string context; + TSNode parent = ts_node_parent(node); + if (!ts_node_is_null(parent)) + context = ts_node_type(parent); + errors.push_back(ParseError::Unexpected(loc, type, context)); + } + } + + uint32_t count = ts_node_child_count(node); + for (uint32_t i = 0; i < count; i++) + { + TSNode child = ts_node_child(node, i); + auto child_errors = CollectSyntaxErrors(child, source); + errors.insert(errors.end(), + std::make_move_iterator(child_errors.begin()), + std::make_move_iterator(child_errors.end())); + } + + return errors; + } + + // ===== 通用解析函数 ===== + + Signature ParseSignature(TSNode node, ParseContext& ctx) + { + Signature sig; + + TSNode params_node = ts_node_child_by_field_name(node, "parameters", 10); + if (!ts_node_is_null(params_node)) + sig.parameters = ParseParameters(params_node, ctx); + + TSNode return_node = ts_node_child_by_field_name(node, "return_type", 11); + if (!ts_node_is_null(return_node)) + { + TSNode type_name_node = ts_node_child_by_field_name(return_node, "type_name", 9); + if (!ts_node_is_null(type_name_node)) + sig.return_type = ts::Text(type_name_node, ctx.Source()); + } + + return sig; + } + + std::vector ParseParameters(TSNode params_node, ParseContext& ctx) + { + std::vector all_params; + + uint32_t count = ts_node_child_count(params_node); + for (uint32_t i = 0; i < count; i++) + { + const char* field_name = ts_node_field_name_for_child(params_node, i); + if (!field_name || std::string_view(field_name) != "parameter") + continue; + + TSNode param_node = ts_node_child(params_node, i); + bool is_var = false; + bool is_out = false; + + uint32_t param_count = ts_node_child_count(param_node); + for (uint32_t j = 0; j < param_count; j++) + { + TSNode child = ts_node_child(param_node, j); + std::string text = ts::Text(child, ctx.Source()); + if (text == "var") + is_var = true; + if (text == "out") + is_out = true; + } + + std::optional type_name; + TSNode type_node = ts_node_child_by_field_name(param_node, "type_name", 9); + if (!ts_node_is_null(type_node)) + type_name = ts::Text(type_node, ctx.Source()); + + ExpressionPtr default_value; + TSNode default_node = ts_node_child_by_field_name(param_node, "default", 7); + if (!ts_node_is_null(default_node)) + default_value = ParseExpression(default_node, ctx); + + for (uint32_t j = 0; j < param_count; j++) + { + const char* field = ts_node_field_name_for_child(param_node, j); + + if (!field || std::string_view(field) != "name") + continue; + + TSNode child = ts_node_child(param_node, j); + + Parameter param; + param.name = ts::Text(child, ctx.Source()); + param.type_name = std::nullopt; + param.is_var = is_var; + param.is_out = is_out; + param.location = ts::NodeLocation(child); + + all_params.push_back(std::move(param)); + } + + if (!all_params.empty()) + { + all_params.back().type_name = type_name; + all_params.back().default_value = std::move(default_value); + } + } + + return all_params; + } + + // ===== 表达式解析 ===== + + ExpressionPtr ParseExpression(TSNode node, ParseContext& ctx) + { + std::string_view node_type = ts_node_type(node); + + if (node_type == "expression") + { + uint32_t count = ts_node_child_count(node); + for (uint32_t i = 0; i < count; i++) + { + TSNode child = ts_node_child(node, i); + if (ts_node_is_named(child)) + return ParseExpression(child, ctx); + } + return ctx.ReportNullNode(ts::NodeLocation(node), "sub expression"); + } + + // 二元表达式 + if (node_type == "binary_expression") + return ParseBinaryExpression(node, ctx); + + // 一元表达式 + if (node_type == "unary_expression" || + node_type == "prefix_increment_expression" || + node_type == "prefix_decrement_expression" || + node_type == "postfix_increment_expression" || + node_type == "postfix_decrement_expression" || + node_type == "function_pointer_expression" || + node_type == "expr_expression") + { + return ParseUnaryExpression(node, ctx); + } + + // 三元表达式 + if (node_type == "ternary_expression") + return ParseTernaryExpression(node, ctx); + + // 函数调用 + if (node_type == "call") + return ParseCallExpression(node, ctx); + + // 属性访问 + if (node_type == "attribute") + return ParseAttributeExpression(node, ctx); + + // 下标访问 + if (node_type == "subscript") + return ParseSubscriptExpression(node, ctx); + + // 数组 + if (node_type == "array") + return ParseArrayExpression(node, ctx); + + // 匿名函数 + if (node_type == "anonymous_function_expression") + return ParseAnonymousFunctionExpression(node, ctx); + + // 赋值表达式 + if (node_type == "assignment_expression" || node_type == "augmented_assignment_expression") + return ParseAssignmentExpression(node, ctx); + + // 内置表达式 + if (node_type == "echo_expression") + return ParseEchoExpression(node, ctx); + if (node_type == "raise_expression") + return ParseRaiseExpression(node, ctx); + if (node_type == "new_expression") + return ParseNewExpression(node, ctx); + if (node_type == "inherited_expression") + return ParseInheritedExpression(node, ctx); + + // TSSQL 选择表达式 + if (node_type == "select_expression" || + node_type == "sselect_expression" || + node_type == "vselect_expression" || + node_type == "mselect_expression" || + node_type == "update_expression" || + node_type == "delete_expression" || + node_type == "insert_expression") + { + return ParseTSSQLExpression(node, ctx); + } + + // 主表达式(标识符、字面量等) + return ParsePrimaryExpression(node, ctx); + } + + ExpressionPtr ParseTSSQLExpression(TSNode node, ParseContext& ctx) + { + std::string_view node_type = ts_node_type(node); + Location loc = ts::NodeLocation(node); + + auto expr = MakeNode(); + expr->location = loc; + expr->node_type_name = node_type; + expr->raw_sql = ts::Text(node, ctx.Source()); + + // 根据节点类型设置SQL类型 + if (node_type == "select_expression") + expr->sql_type = TSSQLExpressionType::kSelect; + else if (node_type == "sselect_expression") + expr->sql_type = TSSQLExpressionType::kSSelect; + else if (node_type == "vselect_expression") + expr->sql_type = TSSQLExpressionType::kVSelect; + else if (node_type == "mselect_expression") + expr->sql_type = TSSQLExpressionType::kMSelect; + else if (node_type == "update_expression") + expr->sql_type = TSSQLExpressionType::kUpdate; + else if (node_type == "delete_expression") + expr->sql_type = TSSQLExpressionType::kDelete; + else if (node_type == "insert_expression") + expr->sql_type = TSSQLExpressionType::kInsert; + else + expr->sql_type = TSSQLExpressionType::kSelect; + + return expr; + } + + ExpressionPtr ParseEchoExpression(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + auto echo_id = MakeNode(); + echo_id->kind = NodeKind::kIdentifier; + echo_id->location = loc; + echo_id->node_type_name = "identifier"; + echo_id->name = "echo"; + + auto call = MakeNode(); + call->kind = NodeKind::kCallExpression; + call->location = loc; + call->node_type_name = "call_expression"; + call->callee = std::move(echo_id); + + uint32_t count = ts_node_child_count(node); + for (uint32_t i = 0; i < count; i++) + { + const char* field = ts_node_field_name_for_child(node, i); + if (!field || std::string_view(field) != "argument") + continue; + + auto expr = ParseExpression(ts_node_child(node, i), ctx); + if (expr) + { + CallExpression::Argument arg; + arg.value = std::move(expr); + call->arguments.push_back(std::move(arg)); + } + } + + return call; + } + + ExpressionPtr ParseRaiseExpression(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + auto raise_id = MakeNode(); + raise_id->kind = NodeKind::kIdentifier; + raise_id->location = loc; + raise_id->node_type_name = "identifier"; + raise_id->name = "raise"; + + auto call = MakeNode(); + call->kind = NodeKind::kCallExpression; + call->location = loc; + call->node_type_name = "call_expression"; + call->callee = std::move(raise_id); + + TSNode exception_node = ts_node_child_by_field_name(node, "exception", 9); + if (!ts_node_is_null(exception_node)) + { + auto expr = ParseExpression(exception_node, ctx); + if (expr) + { + CallExpression::Argument arg; + arg.value = std::move(expr); + call->arguments.push_back(std::move(arg)); + } + } + return call; + } + + ExpressionPtr ParseNewExpression(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + auto new_id = MakeNode(); + new_id->kind = NodeKind::kIdentifier; + new_id->location = loc; + new_id->node_type_name = "identifier"; + new_id->name = "new"; + + auto call = MakeNode(); + call->kind = NodeKind::kCallExpression; + call->location = loc; + call->node_type_name = "call_expression"; + call->callee = std::move(new_id); + + TSNode exception_node = ts_node_child_by_field_name(node, "class", 5); + if (!ts_node_is_null(exception_node)) + { + auto expr = ParseExpression(exception_node, ctx); + if (expr) + { + CallExpression::Argument arg; + arg.value = std::move(expr); + call->arguments.push_back(std::move(arg)); + } + } + + return call; + } + + ExpressionPtr ParseInheritedExpression(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + auto new_id = MakeNode(); + new_id->kind = NodeKind::kIdentifier; + new_id->location = loc; + new_id->node_type_name = "identifier"; + new_id->name = "inherited"; + + auto call = MakeNode(); + call->kind = NodeKind::kCallExpression; + call->location = loc; + call->node_type_name = "call_expression"; + call->callee = std::move(new_id); + + TSNode exception_node = ts_node_child_by_field_name(node, "class", 5); + if (!ts_node_is_null(exception_node)) + { + auto expr = ParseExpression(exception_node, ctx); + if (expr) + { + CallExpression::Argument arg; + arg.value = std::move(expr); + call->arguments.push_back(std::move(arg)); + } + } + + return call; + } + + ExpressionPtr ParsePrimaryExpression(TSNode node, ParseContext& ctx) + { + std::string_view node_type = ts_node_type(node); + Location loc = ts::NodeLocation(node); + + if (node_type == "literal" || node_type == "reserved_keyword") + { + uint32_t count = ts_node_child_count(node); + for (uint32_t i = 0; i < count; i++) + { + TSNode child = ts_node_child(node, i); + if (ts_node_is_named(child)) + return ParsePrimaryExpression(child, ctx); + } + return nullptr; + } + + // 标识符 + if (node_type == "identifier" || node_type == "type" || + node_type == "class" || node_type == "do") + { + std::string name = ts::Text(node, ctx.Source()); + auto id = MakeNode(); + id->kind = NodeKind::kIdentifier; + id->location = loc; + id->node_type_name = node_type; + id->name = std::move(name); + return id; + } + + // 字面量 + if (node_type == "number") + { + std::string value = ts::Text(node, ctx.Source()); + auto lit = MakeNode(); + lit->kind = NodeKind::kLiteral; + lit->location = loc; + lit->node_type_name = "literal"; + lit->literal_kind = LiteralKind::kNumber; + lit->value = std::move(value); + return lit; + } + + if (node_type == "string") + { + std::string value = ts::Text(node, ctx.Source()); + auto lit = MakeNode(); + lit->kind = NodeKind::kLiteral; + lit->location = loc; + lit->node_type_name = "literal"; + lit->literal_kind = LiteralKind::kString; + lit->value = std::move(value); + return lit; + } + + if (node_type == "boolean") + { + std::string value = ts::Text(node, ctx.Source()); + auto lit = MakeNode(); + lit->kind = NodeKind::kLiteral; + lit->location = loc; + lit->node_type_name = "literal"; + lit->literal_kind = LiteralKind::kBoolean; + lit->value = std::move(value); + return lit; + } + + if (node_type == "nil") + { + auto lit = MakeNode(); + lit->kind = NodeKind::kLiteral; + lit->location = loc; + lit->node_type_name = "literal"; + lit->literal_kind = LiteralKind::kNil; + lit->value = "nil"; + return lit; + } + + if (node_type == "infinity") + { + std::string value = ts::Text(node, ctx.Source()); + auto lit = MakeNode(); + lit->kind = NodeKind::kLiteral; + lit->location = loc; + lit->node_type_name = "literal"; + lit->literal_kind = LiteralKind::kInfinity; + lit->value = std::move(value); + return lit; + } + + if (node_type == "ellipsis") + { + auto lit = MakeNode(); + lit->kind = NodeKind::kLiteral; + lit->location = loc; + lit->node_type_name = "literal"; + lit->literal_kind = LiteralKind::kEllipsis; + lit->value = "..."; + return lit; + } + + // 默认:创建一个标识符表达式 + std::string text = ts::Text(node, ctx.Source()); + if (!text.empty()) + { + auto id = MakeNode(); + id->kind = NodeKind::kIdentifier; + id->location = loc; + id->node_type_name = "identifier"; + id->name = std::move(text); + return id; + } + + return nullptr; + } + + ExpressionPtr ParseBinaryExpression(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + TSNode left_node = ts_node_child_by_field_name(node, "left", 4); + TSNode right_node = ts_node_child_by_field_name(node, "right", 5); + TSNode op_node = ts_node_child_by_field_name(node, "operator", 8); + + if (ts_node_is_null(left_node)) + return ctx.ReportNullNode(loc, "left operand"); + + if (ts_node_is_null(right_node)) + return ctx.ReportNullNode(loc, "right operand"); + + auto left = ParseExpression(left_node, ctx); + auto right = ParseExpression(right_node, ctx); + + if (!left) + return ctx.ReportParseFailed(loc, "binary_expression", "failed to parse left operand"); + + if (!right) + return ctx.ReportParseFailed(loc, "binary_expression", "failed to parse right operand"); + + std::string op_text; + if (!ts_node_is_null(op_node)) + op_text = ts::Text(op_node, ctx.Source()); + else + ctx.RecordMissing(loc, "operator"); + + BinaryOperator op = ParseBinaryOperator(op_text); + + auto expr = MakeNode(); + expr->kind = NodeKind::kBinaryExpression; + expr->location = loc; + expr->node_type_name = "binary_expression"; + expr->op = op; + expr->left = std::move(left); + expr->right = std::move(right); + return expr; + } + + ExpressionPtr ParseUnaryExpression(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + std::string_view node_type = ts_node_type(node); + + // 前缀自增/自减 + if (node_type == "prefix_increment_expression") + { + TSNode arg_node = ts_node_child_by_field_name(node, "argument", 8); + auto arg = ParseExpression(arg_node, ctx); + auto expr = MakeNode(); + expr->kind = NodeKind::kPrefixIncrementExpression; + expr->location = loc; + expr->node_type_name = "prefix_increment_expression"; + expr->argument = std::move(arg); + return expr; + } + + if (node_type == "prefix_decrement_expression") + { + TSNode arg_node = ts_node_child_by_field_name(node, "argument", 8); + auto arg = ParseExpression(arg_node, ctx); + auto expr = MakeNode(); + expr->kind = NodeKind::kPrefixDecrementExpression; + expr->location = loc; + expr->node_type_name = "prefix_decrement_expression"; + expr->argument = std::move(arg); + return expr; + } + + // 后缀自增/自减 + if (node_type == "postfix_increment_expression") + { + TSNode arg_node = ts_node_child_by_field_name(node, "argument", 8); + auto arg = ParseExpression(arg_node, ctx); + auto expr = MakeNode(); + expr->kind = NodeKind::kPostfixIncrementExpression; + expr->location = loc; + expr->node_type_name = "postfix_increment_expression"; + expr->argument = std::move(arg); + return expr; + } + + if (node_type == "postfix_decrement_expression") + { + TSNode arg_node = ts_node_child_by_field_name(node, "argument", 8); + auto arg = ParseExpression(arg_node, ctx); + auto expr = MakeNode(); + expr->kind = NodeKind::kPostfixDecrementExpression; + expr->location = loc; + expr->node_type_name = "postfix_decrement_expression"; + expr->argument = std::move(arg); + return expr; + } + + // 函数指针 + if (node_type == "function_pointer_expression") + { + TSNode arg_node = ts_node_child_by_field_name(node, "argument", 8); + auto arg = ParseExpression(arg_node, ctx); + auto expr = MakeNode(); + expr->kind = NodeKind::kFunctionPointerExpression; + expr->location = loc; + expr->node_type_name = "function_pointer_expression"; + expr->argument = std::move(arg); + return expr; + } + + // 通用一元表达式 + TSNode op_node = ts_node_child_by_field_name(node, "operator", 8); + TSNode arg_node = ts_node_child_by_field_name(node, "argument", 8); + + if (ts_node_is_null(arg_node)) + return ctx.ReportNullNode(ts::NodeLocation(node), "argument"); + + auto arg = ParseExpression(arg_node, ctx); + if (!arg) + return ctx.ReportParseFailed(ts::NodeLocation(arg_node), ts_node_type(arg_node), "argument"); + + std::string op_text; + if (!ts_node_is_null(op_node)) + op_text = ts::Text(op_node, ctx.Source()); + + UnaryOperator op = ParseUnaryOperator(op_text); + + auto expr = MakeNode(); + expr->kind = NodeKind::kUnaryExpression; + expr->location = loc; + expr->node_type_name = "unary_expression"; + expr->op = op; + expr->argument = std::move(arg); + return expr; + } + + ExpressionPtr ParseTernaryExpression(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + TSNode cond_node = ts_node_child_by_field_name(node, "condition", 9); + TSNode cons_node = ts_node_child_by_field_name(node, "consequence", 11); + TSNode alt_node = ts_node_child_by_field_name(node, "alternative", 11); + + if (ts_node_is_null(cond_node)) + return ctx.ReportNullNode(loc, "condition"); + + if (ts_node_is_null(alt_node)) + return ctx.ReportNullNode(loc, "alternative"); + + auto condition = ParseExpression(cond_node, ctx); + auto alternative = ParseExpression(alt_node, ctx); + + ExpressionPtr consequence; + if (!ts_node_is_null(cons_node)) + consequence = ParseExpression(cons_node, ctx); + + auto expr = MakeNode(); + expr->kind = NodeKind::kTernaryExpression; + expr->location = loc; + expr->node_type_name = "ternary_expression"; + expr->condition = std::move(condition); + expr->consequence = std::move(consequence); + expr->alternative = std::move(alternative); + return expr; + } + + ExpressionPtr ParseCallExpression(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + TSNode callee_node = ts_node_child_by_field_name(node, "function", 8); + + if (ts_node_is_null(callee_node)) + return ctx.ReportNullNode(loc, "function callee"); + + auto callee = ParseExpression(callee_node, ctx); + + if (!callee) + return ctx.ReportParseFailed(loc, "call_expression", "failed to parse callee"); + + std::vector arguments; + + uint32_t count = ts_node_child_count(node); + for (uint32_t i = 0; i < count; i++) + { + const char* field = ts_node_field_name_for_child(node, i); + if (!field || std::string_view(field) != "argument") + continue; + + TSNode argument_node = ts_node_child(node, i); + + TSNode child = ts_node_child(argument_node, 0); + std::string_view child_node_type = ts_node_type(child); + + CallExpression::Argument arg; + if (child_node_type == "expression") + { + arg.value = ParseExpression(child, ctx); + } + else if (child_node_type == "named_argument") + { + TSNode name_node = ts_node_child_by_field_name(child, "name", 4); + if (!ts_node_is_null(name_node)) + arg.name = ts::Text(name_node, ctx.Source()); + + TSNode value_node = ts_node_child_by_field_name(child, "value", 5); + if (!ts_node_is_null(value_node)) + arg.value = ParseExpression(value_node, ctx); + } + arguments.push_back(std::move(arg)); + } + + auto expr = MakeNode(); + expr->kind = NodeKind::kCallExpression; + expr->location = loc; + expr->node_type_name = "call_expression"; + expr->callee = std::move(callee); + expr->arguments = std::move(arguments); + return expr; + } + + ExpressionPtr ParseAttributeExpression(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + TSNode obj_node = ts_node_child_by_field_name(node, "object", 6); + TSNode attr_node = ts_node_child_by_field_name(node, "attribute", 9); + + if (ts_node_is_null(obj_node)) + return ctx.ReportNullNode(loc, "object"); + + if (ts_node_is_null(attr_node)) + return ctx.ReportNullNode(loc, "attribute"); + + auto object = ParseExpression(obj_node, ctx); + if (!object) + return ctx.ReportParseFailed(loc, "attribute_expression", "failed to parse object"); + + std::string attribute = ts::Text(attr_node, ctx.Source()); + + auto expr = MakeNode(); + expr->kind = NodeKind::kAttributeExpression; + expr->location = loc; + expr->node_type_name = "attribute_expression"; + expr->object = std::move(object); + expr->attribute = std::move(attribute); + return expr; + } + + ExpressionPtr ParseSubscriptExpression(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + TSNode value_node = ts_node_child_by_field_name(node, "value", 5); + + if (ts_node_is_null(value_node)) + { + ctx.RecordMissing(loc, "value"); + return nullptr; + } + + auto value = ParseExpression(value_node, ctx); + + if (!value) + return nullptr; + + std::vector indices; + + TSNode subscript_node = ts_node_child_by_field_name(node, "subscript", 9); + if (!ts_node_is_null(subscript_node)) + { + uint32_t count = ts_node_child_count(subscript_node); + for (uint32_t i = 0; i < count; i++) + { + TSNode idx_node = ts_node_child(subscript_node, i); + if (!ts_node_is_named(idx_node)) + continue; + + std::string_view idx_type = ts_node_type(idx_node); + SubscriptExpression::Index idx; + + if (idx_type == "slice" || idx_type == "range_slice" || + idx_type == "start_slice" || idx_type == "end_slice" || + idx_type == "step_slice") + { + idx.is_slice = true; + int part = 0; + uint32_t count = ts_node_child_count(idx_node); + for (uint32_t i = 0; i < count; i++) + { + TSNode slice_child = ts_node_child(idx_node, i); + if (!ts_node_is_named(slice_child)) + { + if (ts::Text(slice_child, ctx.Source()) == ":") + part++; + continue; + } + + auto expr = ParseExpression(slice_child, ctx); + if (part == 0) + idx.start = std::move(expr); + else if (part == 1) + idx.end = std::move(expr); + else if (part == 2) + idx.step = std::move(expr); + } + } + else if (idx_type == "empty_slice") + { + idx.is_empty_slice = true; + } + else + { + idx.start = ParseExpression(idx_node, ctx); + } + + indices.push_back(std::move(idx)); + } + } + + auto expr = MakeNode(); + expr->kind = NodeKind::kSubscriptExpression; + expr->location = loc; + expr->node_type_name = "subscript_expression"; + expr->value = std::move(value); + expr->indices = std::move(indices); + return expr; + } + + ExpressionPtr ParseArrayExpression(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + std::vector elements; + + uint32_t count = ts_node_child_count(node); + for (uint32_t i = 0; i < count; i++) + { + TSNode child = ts_node_child(node, i); + if (!ts_node_is_named(child)) + continue; + + std::string_view child_type = ts_node_type(child); + + if (child_type == "array_element" || child_type == "key_value_pair") + { + ArrayExpression::Element elem; + + TSNode key_node = ts_node_child_by_field_name(child, "key", 3); + TSNode value_node = ts_node_child_by_field_name(child, "value", 5); + + if (!ts_node_is_null(key_node)) + { + elem.key = ParseExpression(key_node, ctx); + } + + if (!ts_node_is_null(value_node)) + { + elem.value = ParseExpression(value_node, ctx); + } + else if (ts_node_is_null(key_node)) + { + elem.value = ParseExpression(child, ctx); + } + + elements.push_back(std::move(elem)); + } + else if (child_type == "parenthesized_array") + { + ArrayExpression::Element elem; + elem.is_nested = true; + elem.value = ParseArrayExpression(child, ctx); + elements.push_back(std::move(elem)); + } + } + + auto expr = MakeNode(); + expr->kind = NodeKind::kArrayExpression; + expr->location = loc; + expr->node_type_name = "array_expression"; + expr->elements = std::move(elements); + return expr; + } + + ExpressionPtr ParseAnonymousFunctionExpression(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + Signature sig = ParseSignature(node, ctx); + + TSNode body_node = ts_node_child_by_field_name(node, "body", 4); + auto body = ParseBlockSuite(body_node, ctx); + + auto expr = MakeNode(); + expr->kind = NodeKind::kAnonymousFunctionExpression; + expr->location = loc; + expr->node_type_name = "anonymous_function_expression"; + expr->signature = std::move(sig); + expr->body = std::move(body); + return expr; + } + + // ===== 左值解析(用于赋值语句) ===== + + LeftHandSide ParseLeftHandSide(TSNode node, ParseContext& ctx) + { + if (ts_node_is_null(node)) + { + auto id = MakeNode(); + id->kind = NodeKind::kIdentifier; + id->location = ts::NodeLocation(node); + id->node_type_name = "identifier"; + id->name = ""; + return id; + } + + std::string_view node_type = ts_node_type(node); + + // 标识符 + if (node_type == "identifier" || node_type == "type" || + node_type == "class" || node_type == "do") + { + std::string name = ts::Text(node, ctx.Source()); + Location loc = ts::NodeLocation(node); + auto id = MakeNode(); + id->kind = NodeKind::kIdentifier; + id->location = loc; + id->node_type_name = "identifier"; + id->name = std::move(name); + return id; + } + + // 属性访问 + if (node_type == "attribute") + { + return std::unique_ptr( + static_cast(ParseAttributeExpression(node, ctx).release())); + } + + // 下标访问 + if (node_type == "subscript") + { + return std::unique_ptr( + static_cast(ParseSubscriptExpression(node, ctx).release())); + } + + // 解包模式 + if (node_type == "unpack_pattern") + { + return ParseUnpackPattern(node, ctx); + } + + auto id = MakeNode(); + id->kind = NodeKind::kIdentifier; + id->location = ts::NodeLocation(node); + id->node_type_name = "identifier"; + id->name = ts::Text(node, ctx.Source()); + return id; + } + + std::unique_ptr ParseUnpackPattern(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + std::vector names; + + uint32_t count = ts_node_child_count(node); + for (uint32_t i = 0; i < count; i++) + { + const char* field = ts_node_field_name_for_child(node, i); + if (field && std::string_view(field) == "name") + names.push_back(ts::Text(ts_node_child(node, i), ctx.Source())); + } + + auto pattern = MakeNode(); + pattern->kind = NodeKind::kUnpackPattern; + pattern->location = loc; + pattern->node_type_name = "unpack_pattern"; + pattern->names = std::move(names); + return pattern; + } + + // ===== 语句解析 ===== + + StatementPtr ParseStatement(TSNode node, ParseContext& ctx) + { + if (ts_node_is_null(node)) + return nullptr; + + std::string node_type = ts_node_type(node); + + // 查找注册的解析器 + auto parser = StatementParserRegistry::Instance().Get(node_type); + if (parser) + return parser(node, ctx); + + // 默认作为表达式语句处理 + return ParseExpressionStatement(node, ctx); + } + + StatementPtr ParseSingleSuite(TSNode node, ParseContext& ctx) + { + TSNode child = ts_node_child(node, 0); + std::string node_type = ts_node_type(child); + auto parser = StatementParserRegistry::Instance().Get(node_type); + if (parser) + return parser(child, ctx); + return nullptr; + } + + StatementPtr ParseBlockSuite(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + std::vector statements; + + uint32_t count = ts_node_child_count(node); + for (uint32_t i = 0; i < count; i++) + { + TSNode child = ts_node_child(node, i); + + if (!ts_node_is_named(child)) + continue; + + if (ts::IsComment(child)) + continue; + + auto stmt = ParseStatement(child, ctx); + if (stmt) + statements.push_back(std::move(stmt)); + } + + auto block = MakeNode(); + block->kind = NodeKind::kBlockStatement; + block->location = loc; + block->node_type_name = "block_suit"; + block->statements = std::move(statements); + return block; + } + + StatementPtr ParseExpressionStatement(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + ExpressionPtr expr = nullptr; + uint32_t count = ts_node_child_count(node); + for (uint32_t i = 0; i < count; i++) + { + TSNode child = ts_node_child(node, i); + if (ts_node_is_named(child)) + { + expr = ParseExpression(child, ctx); + break; + } + } + if (!expr) + return nullptr; + + auto stmt = MakeNode(); + stmt->kind = NodeKind::kExpressionStatement; + stmt->location = loc; + stmt->node_type_name = "expression_statement"; + stmt->expression = std::move(expr); + return stmt; + } + + ExpressionPtr ParseAssignmentExpression(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + std::string_view node_type = ts_node_type(node); + + TSNode left_node = ts_node_child_by_field_name(node, "left", 4); + TSNode op_node = ts_node_child_by_field_name(node, "operator", 8); + TSNode right_node = ts_node_child_by_field_name(node, "right", 5); + + if (ts_node_is_null(left_node) || ts_node_is_null(right_node)) + return nullptr; + + LeftHandSide left = ParseLeftHandSide(left_node, ctx); + + AssignmentOperator op = AssignmentOperator::kAssign; + if (!ts_node_is_null(op_node)) + { + std::string op_text = ts::Text(op_node, ctx.Source()); + op = ParseAssignmentOperator(op_text); + } + + auto right = ParseExpression(right_node, ctx); + if (!right) + return nullptr; + + auto expr = MakeNode(); + expr->kind = NodeKind::kAssignmentExpression; + expr->location = loc; + expr->node_type_name = node_type; + expr->left = std::move(left); + expr->op = op; + expr->right = std::move(right); + return expr; + } + + StatementPtr ParseAssignmentStatement(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + TSNode left_node = ts_node_child_by_field_name(node, "left", 4); + TSNode op_node = ts_node_child_by_field_name(node, "operator", 8); + TSNode right_node = ts_node_child_by_field_name(node, "right", 5); + + if (ts_node_is_null(left_node)) + { + uint32_t count = ts_node_child_count(node); + for (uint32_t i = 0; i < count; i++) + { + TSNode child = ts_node_child(node, i); + std::string_view child_type = ts_node_type(child); + if (child_type == "assignment_expression" || child_type == "augmented_assignment_expression") + { + left_node = ts_node_child_by_field_name(child, "left", 4); + op_node = ts_node_child_by_field_name(child, "operator", 8); + right_node = ts_node_child_by_field_name(child, "right", 5); + break; + } + } + } + + if (ts_node_is_null(left_node) || ts_node_is_null(right_node)) + return nullptr; + + LeftHandSide left = ParseLeftHandSide(left_node, ctx); + + AssignmentOperator op = AssignmentOperator::kAssign; + if (!ts_node_is_null(op_node)) + { + std::string op_text = ts::Text(op_node, ctx.Source()); + op = ParseAssignmentOperator(op_text); + } + + auto right = ParseExpression(right_node, ctx); + if (!right) + return nullptr; + + auto stmt = MakeNode(); + stmt->kind = NodeKind::kAssignmentStatement; + stmt->location = loc; + stmt->node_type_name = "assignment_statement"; + stmt->left = std::move(left); + stmt->op = op; + stmt->right = std::move(right); + return stmt; + } + + // ===== 通用声明解析模板 ===== + + template + StatementPtr ParseDeclarationStatement(TSNode node, ParseContext& ctx, NodeKind decl_kind, NodeKind stmt_kind, const std::string& keyword) + { + Location loc = ts::NodeLocation(node); + std::vector> declarations; + + TSNode decl_node = ts_node_child_by_field_name(node, "declaration", 11); + if (!ts_node_is_null(decl_node)) + { + std::optional type_name; + + TSNode type_node = ts_node_child_by_field_name(decl_node, "type_name", 9); + if (!ts_node_is_null(type_node)) + type_name = ts::Text(type_node, ctx.Source()); + + uint32_t count = ts_node_child_count(decl_node); + for (uint32_t i = 0; i < count; i++) + { + const char* field = ts_node_field_name_for_child(decl_node, i); + if (!field || std::string_view(field) != "name") + continue; + TSNode name_node = ts_node_child(decl_node, i); + + std::string name = ts::Text(name_node, ctx.Source()); + Location name_loc = ts::NodeLocation(name_node); + + auto decl = MakeNode(); + decl->kind = decl_kind; + decl->location = name_loc; + decl->node_type_name = keyword + "_declaration"; + decl->name = std::move(name); + decl->type_name = type_name; + decl->initial_value = nullptr; + declarations.push_back(std::move(decl)); + } + + TSNode initial_node = ts_node_child_by_field_name(decl_node, "initial_value", 13); + if (!ts_node_is_null(initial_node)) + declarations.back()->initial_value = ParseExpression(initial_node, ctx); + } + + auto stmt = MakeNode(); + stmt->kind = stmt_kind; + stmt->location = loc; + stmt->node_type_name = keyword + "_statement"; + stmt->declarations = std::move(declarations); + return stmt; + } + + StatementPtr ParseVarStatement(TSNode node, ParseContext& ctx) + { + return ParseDeclarationStatement( + node, ctx, NodeKind::kVarDeclaration, NodeKind::kVarStatement, "var"); + } + + StatementPtr ParseStaticStatement(TSNode node, ParseContext& ctx) + { + return ParseDeclarationStatement( + node, ctx, NodeKind::kStaticDeclaration, NodeKind::kStaticStatement, "static"); + } + + StatementPtr ParseGlobalStatement(TSNode node, ParseContext& ctx) + { + return ParseDeclarationStatement( + node, ctx, NodeKind::kGlobalDeclaration, NodeKind::kGlobalStatement, "global"); + } + + StatementPtr ParseConstStatement(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + TSNode name_node = ts_node_child_by_field_name(node, "name", 4); + std::string name = ts_node_is_null(name_node) ? "" : ts::Text(name_node, ctx.Source()); + + std::optional type_name; + TSNode type_node = ts_node_child_by_field_name(node, "type_name", 9); + if (!ts_node_is_null(type_node)) + { + type_name = ts::Text(type_node, ctx.Source()); + } + + TSNode value_node = ts_node_child_by_field_name(node, "value", 5); + auto value = ParseExpression(value_node, ctx); + + auto stmt = MakeNode(); + stmt->kind = NodeKind::kConstStatement; + stmt->location = loc; + stmt->node_type_name = "const_statement"; + stmt->name = std::move(name); + stmt->type_name = type_name; + stmt->value = std::move(value); + return stmt; + } + + StatementPtr ParseIfStatement(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + std::vector branches; + + uint32_t count = ts_node_child_count(node); + for (uint32_t i = 0; i < count; i++) + { + TSNode child = ts_node_child(node, i); + std::string_view node_type = ts_node_type(child); + if (node_type == "if_clause") + { + IfStatement::Branch branch; + + TSNode cond_node = ts_node_child_by_field_name(child, "condition", 9); + branch.condition = ParseExpression(cond_node, ctx); + TSNode cons_node = ts_node_child_by_field_name(child, "consequence", 11); + branch.body = ParseStatement(cons_node, ctx); + + branches.push_back(std::move(branch)); + } + else if (node_type == "else_if_clause") + { + IfStatement::Branch branch; + TSNode cond_node = ts_node_child_by_field_name(child, "condition", 9); + branch.condition = ParseExpression(cond_node, ctx); + + TSNode cons_node = ts_node_child_by_field_name(child, "consequence", 11); + branch.body = ParseStatement(cons_node, ctx); + + branches.push_back(std::move(branch)); + } + else if (node_type == "else_clause") + { + IfStatement::Branch branch; + branch.condition = nullptr; + + TSNode cons_node = ts_node_child_by_field_name(child, "consequence", 11); + branch.body = ParseStatement(cons_node, ctx); + + branches.push_back(std::move(branch)); + } + } + + auto stmt = MakeNode(); + stmt->kind = NodeKind::kIfStatement; + stmt->location = loc; + stmt->node_type_name = "if_statement"; + stmt->branches = std::move(branches); + return stmt; + } + + StatementPtr ParseForInStatement(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + TSNode key_node = ts_node_child_by_field_name(node, "key", 3); + TSNode value_node = ts_node_child_by_field_name(node, "value", 5); + TSNode collection_node = ts_node_child_by_field_name(node, "collection", 10); + TSNode body_node = ts_node_child_by_field_name(node, "body", 4); + + std::string key = ts_node_is_null(key_node) ? "" : ts::Text(key_node, ctx.Source()); + std::string value = ts_node_is_null(value_node) ? "" : ts::Text(value_node, ctx.Source()); + auto collection = ParseExpression(collection_node, ctx); + auto body = ParseStatement(body_node, ctx); + + auto stmt = MakeNode(); + stmt->kind = NodeKind::kForInStatement; + stmt->location = loc; + stmt->node_type_name = "for_in_statement"; + stmt->key = std::move(key); + stmt->value = std::move(value); + stmt->collection = std::move(collection); + stmt->body = std::move(body); + return stmt; + } + + StatementPtr ParseForToStatement(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + TSNode counter_node = ts_node_child_by_field_name(node, "counter", 7); + TSNode start_node = ts_node_child_by_field_name(node, "start", 5); + TSNode end_node = ts_node_child_by_field_name(node, "end", 3); + TSNode direction_node = ts_node_child_by_field_name(node, "direction", 9); + TSNode body_node = ts_node_child_by_field_name(node, "body", 4); + + std::string counter = ts_node_is_null(counter_node) ? "" : ts::Text(counter_node, ctx.Source()); + auto start = ParseExpression(start_node, ctx); + auto end = ParseExpression(end_node, ctx); + + bool is_downto = false; + if (!ts_node_is_null(direction_node)) + { + std::string direction = ts::Text(direction_node, ctx.Source()); + is_downto = (direction == "downto"); + } + + auto body = ParseStatement(body_node, ctx); + + auto stmt = MakeNode(); + stmt->kind = NodeKind::kForToStatement; + stmt->location = loc; + stmt->node_type_name = "for_to_statement"; + stmt->counter = std::move(counter); + stmt->start = std::move(start); + stmt->end = std::move(end); + stmt->is_downto = is_downto; + stmt->body = std::move(body); + return stmt; + } + + StatementPtr ParseWhileStatement(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + TSNode condition_node = ts_node_child_by_field_name(node, "condition", 9); + TSNode body_node = ts_node_child_by_field_name(node, "body", 4); + + auto condition = ParseExpression(condition_node, ctx); + auto body = ParseStatement(body_node, ctx); + + auto stmt = MakeNode(); + stmt->kind = NodeKind::kWhileStatement; + stmt->location = loc; + stmt->node_type_name = "while_statement"; + stmt->condition = std::move(condition); + stmt->body = std::move(body); + return stmt; + } + + StatementPtr ParseRepeatStatement(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + TSNode condition_node = ts_node_child_by_field_name(node, "condition", 9); + + std::vector body_statements; + std::string name = "body"; + uint32_t count = ts_node_child_count(node); + for (uint32_t i = 0; i < count; i++) + { + const char* field = ts_node_field_name_for_child(node, i); + if (!field || name != field) + continue; + TSNode child = ts_node_child(node, i); + + auto stmt = ParseStatement(child, ctx); + if (stmt) + body_statements.push_back(std::move(stmt)); + } + + auto condition = ParseExpression(condition_node, ctx); + + auto stmt = MakeNode(); + stmt->kind = NodeKind::kRepeatStatement; + stmt->location = loc; + stmt->node_type_name = "repeat_statement"; + stmt->body = std::move(body_statements); + stmt->condition = std::move(condition); + return stmt; + } + + StatementPtr ParseCaseStatement(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + TSNode discriminant_node = ts_node_child_by_field_name(node, "discriminant", 12); + auto discriminant = ParseExpression(discriminant_node, ctx); + + std::vector branches; + + std::string name = "branches"; + uint32_t count = ts_node_child_count(node); + for (uint32_t i = 0; i < count; i++) + { + const char* field = ts_node_field_name_for_child(node, i); + if (!field || name != field) + continue; + TSNode branch_node = ts_node_child(node, i); + + CaseStatement::Branch branch; + + std::string value = "value"; + uint32_t branch_count = ts_node_child_count(branch_node); + for (uint32_t j = 0; j < branch_count; j++) + { + const char* field = ts_node_field_name_for_child(branch_node, j); + if (!field || value != field) + continue; + + TSNode value_node = ts_node_child(branch_node, j); + auto value = ParseExpression(value_node, ctx); + if (value) + branch.values.push_back(std::move(value)); + } + + TSNode cons_node = ts_node_child_by_field_name(branch_node, "consequence", 11); + branch.body = ParseStatement(cons_node, ctx); + + branches.push_back(std::move(branch)); + } + + StatementPtr default_case = nullptr; + TSNode default_node = ts_node_child_by_field_name(node, "default", 7); + if (!ts_node_is_null(default_node)) + { + auto cons_node = ts_node_child_by_field_name(default_node, "consequence", 11); + default_case = ParseStatement(cons_node, ctx); + } + + auto stmt = MakeNode(); + stmt->kind = NodeKind::kCaseStatement; + stmt->location = loc; + stmt->node_type_name = "case_statement"; + stmt->discriminant = std::move(discriminant); + stmt->branches = std::move(branches); + stmt->default_case = std::move(default_case); + return stmt; + } + + StatementPtr ParseTryStatement(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + TSNode try_body_node = ts_node_child_by_field_name(node, "try_body", 8); + TSNode except_body_node = ts_node_child_by_field_name(node, "except_body", 11); + + auto try_body = ParseStatement(try_body_node, ctx); + auto except_body = ParseStatement(except_body_node, ctx); + + auto stmt = MakeNode(); + stmt->kind = NodeKind::kTryStatement; + stmt->location = loc; + stmt->node_type_name = "try_statement"; + stmt->try_body = std::move(try_body); + stmt->except_body = std::move(except_body); + return stmt; + } + + StatementPtr ParseBreakStatement(TSNode node, [[maybe_unused]] ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + auto stmt = MakeNode(); + stmt->kind = NodeKind::kBreakStatement; + stmt->location = loc; + stmt->node_type_name = "break_statement"; + return stmt; + } + + StatementPtr ParseContinueStatement(TSNode node, [[maybe_unused]] ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + auto stmt = MakeNode(); + stmt->kind = NodeKind::kContinueStatement; + stmt->location = loc; + stmt->node_type_name = "continue_statement"; + return stmt; + } + + StatementPtr ParseReturnStatement(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + auto stmt = MakeNode(); + stmt->kind = NodeKind::kReturnStatement; + stmt->location = loc; + stmt->node_type_name = "return_statement"; + + TSNode value_node = ts_node_child_by_field_name(node, "value", 5); + if (!ts_node_is_null(value_node)) + { + auto value = ParseExpression(value_node, ctx); + stmt->value = std::move(value); + } + + return stmt; + } + + StatementPtr ParseUsesStatement(TSNode node, [[maybe_unused]] ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + auto uses = MakeNode(); + uses->kind = NodeKind::kUsesStatement; + uses->location = loc; + uses->node_type_name = "uses_statement"; + + uint32_t count = ts_node_child_count(node); + for (uint32_t i = 0; i < count; i++) + { + const char* field = ts_node_field_name_for_child(node, i); + if (!field || std::string_view(field) != "module") + continue; + + TSNode child = ts_node_child(node, i); + uses->modules.push_back(std::move(ts::Text(child, ctx.Source()))); + } + return uses; + } + + StatementPtr ParseInheritedStatement(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + ExpressionPtr expr = nullptr; + + TSNode class_node = ts_node_child_by_field_name(node, "class", 5); + if (!ts_node_is_null(class_node)) + expr = ParseExpression(class_node, ctx); + + auto stmt = MakeNode(); + stmt->kind = NodeKind::kExpressionStatement; + stmt->location = loc; + stmt->node_type_name = "inherited_statement"; + stmt->expression = std::move(expr); + return stmt; + } + + StatementPtr ParseFunctionDeclaration(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + TSNode name_node = ts_node_child_by_field_name(node, "name", 4); + std::string name = ts_node_is_null(name_node) ? "" : ts::Text(name_node, ctx.Source()); + + Signature sig = ParseSignature(node, ctx); + + auto stmt = MakeNode(); + stmt->kind = NodeKind::kFunctionDeclaration; + stmt->location = loc; + stmt->node_type_name = "function_declaration"; + stmt->name = std::move(name); + stmt->signature = std::move(sig); + return stmt; + } + + StatementPtr ParseFunctionDefinition(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + TSNode name_node = ts_node_child_by_field_name(node, "name", 4); + std::string name = ts_node_is_null(name_node) ? "" : ts::Text(name_node, ctx.Source()); + + Signature sig = ParseSignature(node, ctx); + + TSNode body_node = ts_node_child_by_field_name(node, "body", 4); + auto body = ParseStatement(body_node, ctx); + + std::string_view node_type = ts_node_type(node); + bool is_overload = (node_type == "function_definition_with_overload_statement"); + + auto stmt = MakeNode(); + stmt->kind = NodeKind::kFunctionDefinition; + stmt->location = loc; + stmt->node_type_name = "function_definition"; + stmt->name = std::move(name); + stmt->signature = std::move(sig); + stmt->body = std::move(body); + stmt->is_overload = is_overload; + return stmt; + } + + StatementPtr ParseMatrixIterationStatement(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + TSNode target_node = ts_node_child_by_field_name(node, "target", 6); + TSNode body_node = ts_node_child_by_field_name(node, "body", 4); + + auto target = ParseExpression(target_node, ctx); + auto body = ParseStatement(body_node, ctx); + + auto stmt = MakeNode(); + stmt->kind = NodeKind::kWhileStatement; + stmt->location = loc; + stmt->node_type_name = "matrix_iteration_statement"; + stmt->condition = std::move(target); + stmt->body = std::move(body); + return stmt; + } + + // ===== TSLX 模板解析 ===== + + StatementPtr ParseTSLXOpenTag(TSNode node, [[maybe_unused]] ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + auto block = MakeNode(); + block->kind = NodeKind::kBlockStatement; + block->location = loc; + block->node_type_name = "tslx_open_tag"; + return block; + } + + StatementPtr ParseTSLXCloseTag(TSNode node, [[maybe_unused]] ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + auto block = MakeNode(); + block->kind = NodeKind::kBlockStatement; + block->location = loc; + block->node_type_name = "tslx_close_tag"; + return block; + } + + StatementPtr ParseTSLXOutputTag(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + std::vector expressions; + uint32_t count = ts_node_child_count(node); + for (uint32_t i = 0; i < count; i++) + { + TSNode child = ts_node_child(node, i); + if (!ts_node_is_named(child)) + continue; + + auto expr = ParseExpression(child, ctx); + if (expr) + expressions.push_back(std::move(expr)); + } + + auto block = MakeNode(); + block->kind = NodeKind::kBlockStatement; + block->location = loc; + block->node_type_name = "tslx_output_tag"; + + for (auto& expr : expressions) + { + auto expr_stmt = MakeNode(); + expr_stmt->kind = NodeKind::kExpressionStatement; + expr_stmt->location = expr->location; + expr_stmt->node_type_name = "expression_statement"; + expr_stmt->expression = std::move(expr); + block->statements.push_back(std::move(expr_stmt)); + } + + return block; + } + + StatementPtr ParseTSLXExpressionTag(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + std::vector statements; + uint32_t count = ts_node_child_count(node); + for (uint32_t i = 0; i < count; i++) + { + TSNode child = ts_node_child(node, i); + if (!ts_node_is_named(child)) + continue; + + if (ts::IsComment(child)) + continue; + + auto stmt = ParseStatement(child, ctx); + if (stmt) + statements.push_back(std::move(stmt)); + } + + auto block = MakeNode(); + block->kind = NodeKind::kBlockStatement; + block->location = loc; + block->node_type_name = "tslx_expression_tag"; + block->statements = std::move(statements); + return block; + } + + StatementPtr ParseHTMLSelfClosingTag(TSNode node, [[maybe_unused]] ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + auto block = MakeNode(); + block->kind = NodeKind::kBlockStatement; + block->location = loc; + block->node_type_name = "html_self_closing_tag"; + return block; + } + + StatementPtr ParseHTMLPairedTag(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + std::vector content; + TSNode content_node = ts_node_child_by_field_name(node, "content", 7); + if (!ts_node_is_null(content_node)) + { + uint32_t count = ts_node_child_count(content_node); + for (uint32_t i = 0; i < count; i++) + { + TSNode child = ts_node_child(content_node, i); + if (!ts_node_is_named(child)) + continue; + + auto stmt = ParseStatement(child, ctx); + if (stmt) + content.push_back(std::move(stmt)); + } + } + + auto block = MakeNode(); + block->kind = NodeKind::kBlockStatement; + block->location = loc; + block->node_type_name = "html_paired_tag"; + block->statements = std::move(content); + return block; + } + + StatementPtr ParseHTMLComment(TSNode node, [[maybe_unused]] ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + auto block = MakeNode(); + block->kind = NodeKind::kBlockStatement; + block->location = loc; + block->node_type_name = "html_comment"; + return block; + } + + StatementPtr ParseUnitDefinition(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + TSNode name_node = ts_node_child_by_field_name(node, "name", 4); + std::string unit_name = ts_node_is_null(name_node) ? "" : ts::Text(name_node, ctx.Source()); + + auto unit = MakeNode(); + unit->kind = NodeKind::kUnitDefinition; + unit->location = loc; + unit->node_type_name = "unit_definition"; + unit->name = std::move(unit_name); + + TSNode interface_node = ts_node_child_by_field_name(node, "interface", 9); + if (!ts_node_is_null(interface_node)) + { + uint32_t count = ts_node_child_count(interface_node); + for (uint32_t i = 0; i < count; i++) + { + TSNode child = ts_node_child(interface_node, i); + if (!ts_node_is_named(child)) + continue; + if (ts::IsComment(child)) + continue; + + std::string_view child_type = ts_node_type(child); + if (child_type == "interface") + continue; + + auto stmt = ParseStatement(child, ctx); + if (stmt) + unit->interface_statements.push_back(std::move(stmt)); + } + } + + TSNode impl_node = ts_node_child_by_field_name(node, "implementation", 14); + if (!ts_node_is_null(impl_node)) + { + uint32_t count = ts_node_child_count(impl_node); + for (uint32_t i = 0; i < count; i++) + { + TSNode child = ts_node_child(impl_node, i); + if (!ts_node_is_named(child)) + continue; + if (ts::IsComment(child)) + continue; + + std::string_view child_type = ts_node_type(child); + if (child_type == "implementation") + continue; + + auto stmt = ParseStatement(child, ctx); + if (stmt) + unit->implementation_statements.push_back(std::move(stmt)); + } + } + + TSNode init_node = ts_node_child_by_field_name(node, "initialization", 14); + if (!ts_node_is_null(init_node)) + { + uint32_t count = ts_node_child_count(init_node); + for (uint32_t i = 0; i < count; i++) + { + TSNode child = ts_node_child(init_node, i); + if (!ts_node_is_named(child)) + continue; + if (ts::IsComment(child)) + continue; + + std::string_view child_type = ts_node_type(child); + if (child_type == "initialization") + continue; + + auto stmt = ParseStatement(child, ctx); + if (stmt) + unit->initialization_statements.push_back(std::move(stmt)); + } + } + + TSNode final_node = ts_node_child_by_field_name(node, "finalization", 12); + if (!ts_node_is_null(final_node)) + { + uint32_t count = ts_node_child_count(final_node); + for (uint32_t i = 0; i < count; i++) + { + TSNode child = ts_node_child(final_node, i); + if (!ts_node_is_named(child)) + continue; + if (ts::IsComment(child)) + continue; + + std::string_view child_type = ts_node_type(child); + if (child_type == "finalization") + continue; + + auto stmt = ParseStatement(child, ctx); + if (stmt) + unit->finalization_statements.push_back(std::move(stmt)); + } + } + + return unit; + } + + // ===== Class成员解析 ===== + + AccessModifier ParseAccessModifier(TSNode node, ParseContext& ctx) + { + std::string text = utils::ToLower(ts::Text(node, ctx.Source())); + + if (text == "public") + return AccessModifier::kPublic; + else if (text == "protected") + return AccessModifier::kProtected; + else if (text == "private") + return AccessModifier::kPrivate; + + return AccessModifier::kPublic; + } + + MethodModifier ParseMethodModifier(TSNode node, ParseContext& ctx) + { + std::string text = utils::ToLower(ts::Text(node, ctx.Source())); + + if (text == "virtual") + return MethodModifier::kVirtual; + else if (text == "override") + return MethodModifier::kOverride; + else if (text == "overload") + return MethodModifier::kOverload; + + return MethodModifier::kNone; + } + + ReferenceModifier ParseReferenceModifier(TSNode node, ParseContext& ctx) + { + std::string text = utils::ToLower(ts::Text(node, ctx.Source())); + + if (text == "weakref") + return ReferenceModifier::kWeakRef; + else if (text == "autoref") + return ReferenceModifier::kAutoRef; + + return ReferenceModifier::kNone; + } + + std::unique_ptr ParseMethodDeclaration(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + auto method = MakeNode(); + method->kind = NodeKind::kMethodDeclaration; + method->location = loc; + method->node_type_name = "method_declaration"; + + uint32_t count = ts_node_child_count(node); + for (uint32_t i = 0; i < count; i++) + { + TSNode child = ts_node_child(node, i); + std::string_view child_type = ts_node_type(child); + if (child_type == "class") + { + method->is_class_method = true; + break; + } + } + + TSNode name_node = ts_node_child_by_field_name(node, "name", 4); + if (!ts_node_is_null(name_node)) + { + std::string name_type = ts_node_type(name_node); + if (name_type == "operator_overload") + { + method->is_operator_overload = true; + TSNode op_node = ts_node_child_by_field_name(name_node, "operator", 8); + if (!ts_node_is_null(op_node)) + method->operator_symbol = ts::Text(op_node, ctx.Source()); + } + else + { + method->name = ts::Text(name_node, ctx.Source()); + } + } + + method->signature = ParseSignature(node, ctx); + + TSNode modifier_node = ts_node_child_by_field_name(node, "modifier", 8); + if (!ts_node_is_null(modifier_node)) + method->modifier = ParseMethodModifier(modifier_node, ctx); + + TSNode body_node = ts_node_child_by_field_name(node, "body", 4); + if (!ts_node_is_null(body_node)) + method->body = ParseStatement(body_node, ctx); + + if (utils::ToLower(method->name) == "create") + method->method_type = MethodType::kConstructor; + else if (utils::ToLower(method->name) == "destroy") + method->method_type = MethodType::kDestructor; + + return method; + } + + std::unique_ptr ParsePropertyDeclaration(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + auto prop = MakeNode(); + prop->kind = NodeKind::kPropertyDeclaration; + prop->location = loc; + prop->node_type_name = "property_declaration"; + + TSNode name_node = ts_node_child_by_field_name(node, "name", 4); + if (!ts_node_is_null(name_node)) + prop->name = ts::Text(name_node, ctx.Source()); + + TSNode type_node = ts_node_child_by_field_name(node, "type_name", 9); + if (!ts_node_is_null(type_node)) + prop->type_name = ts::Text(type_node, ctx.Source()); + + TSNode index_node = ts_node_child_by_field_name(node, "index", 5); + if (!ts_node_is_null(index_node)) + prop->index_value = ts::Text(node, ctx.Source()); + + TSNode accessors_node = ts_node_child_by_field_name(node, "accessors", 9); + if (!ts_node_is_null(accessors_node)) + { + TSNode read_node = ts_node_child_by_field_name(accessors_node, "read", 4); + TSNode write_node = ts_node_child_by_field_name(accessors_node, "write", 5); + if (!ts_node_is_null(read_node)) + prop->read_accessor = ts::Text(read_node, ctx.Source()); + if (!ts_node_is_null(write_node)) + prop->write_accessor = ts::Text(write_node, ctx.Source()); + } + + return prop; + } + + std::vector ParseClassMember(TSNode node, ParseContext& ctx, AccessModifier current_access, ReferenceModifier current_reference) + { + std::vector results; + std::string_view node_type = ts_node_type(node); + Location loc = ts::NodeLocation(node); + + // 如果是访问修饰符,返回新的访问级别 + if (node_type == "access_modifier") + { + ClassMemberParseResult result; + result.access_modifier = ParseAccessModifier(node, ctx); + results.push_back(std::move(result)); + return results; + } + + // 如果是引用修饰符,返回新的引用修饰符 + if (node_type == "reference_modifier") + { + ClassMemberParseResult result; + result.reference_modifier = ParseReferenceModifier(node, ctx); + results.push_back(std::move(result)); + return results; + } + + if (node_type == "variable_declaration") + { + bool is_static = false; + + TSNode variable_node = ts_node_child_by_field_name(node, "variable", 8); + if (ts_node_is_null(variable_node)) + return results; + + bool ref_flag = false; + TSNode ref_node = ts_node_child_by_field_name(node, "ref_modifier", 12); + if (!ts_node_is_null(ref_node)) + ref_flag = true; + + TSNode member_var_node = ts_node_child(variable_node, 0); + if (ts_node_is_null(member_var_node)) + return results; + + std::string_view child_type = ts_node_type(member_var_node); + + if (child_type == "static_member_variable") + is_static = true; + else if (child_type == "field_declaration") + is_static = false; + + if (ts_node_is_null(member_var_node)) + return results; + + std::optional type_name; + TSNode type_node = ts_node_child_by_field_name(member_var_node, "type_name", 9); + if (!ts_node_is_null(type_node)) + type_name = ts::Text(type_node, ctx.Source()); + + ExpressionPtr initial_value; + TSNode value_node = ts_node_child_by_field_name(member_var_node, "initial_value", 13); + if (!ts_node_is_null(value_node)) + initial_value = ParseExpression(value_node, ctx); + + uint32_t count = ts_node_child_count(member_var_node); + for (uint32_t i = 0; i < count; i++) + { + const char* field = ts_node_field_name_for_child(member_var_node, i); + if (!field || std::string_view(field) != "name") + continue; + + TSNode name_node = ts_node_child(member_var_node, i); + std::string name = ts::Text(name_node, ctx.Source()); + Location name_loc = ts::NodeLocation(name_node); + + auto member = MakeNode(); + member->kind = NodeKind::kClassMember; + member->location = name_loc; + member->node_type_name = "class_member"; + member->access_modifier = current_access; + + if (is_static) + { + auto decl = MakeNode(); + decl->kind = NodeKind::kStaticDeclaration; + decl->location = name_loc; + decl->node_type_name = "static_declaration"; + decl->name = name; + decl->reference_modifier = ref_flag ? ParseReferenceModifier(ref_node, ctx) : current_reference; + + member->member = std::move(decl); + } + else + { + auto decl = MakeNode(); + decl->kind = NodeKind::kFieldDeclaration; + decl->location = name_loc; + decl->node_type_name = "field_declaration"; + decl->name = name; + decl->reference_modifier = ref_flag ? ParseReferenceModifier(ref_node, ctx) : current_reference; + + member->member = std::move(decl); + } + + ClassMemberParseResult result; + result.member = std::move(member); + results.push_back(std::move(result)); + } + + if (!results.empty()) + { + auto& last_member = results.back().member; + + std::visit([&](auto& decl_ptr) { + using T = std::decay_t; + + if constexpr (std::is_same_v || + std::is_same_v) + { + decl_ptr->type_name = type_name; + decl_ptr->initial_value = std::move(initial_value); + } + }, + last_member->member); + } + } + + else if (node_type == "method_declaration_only" || + node_type == "method_with_modifier" || + node_type == "method_with_implementation") + { + auto member = MakeNode(); + member->kind = NodeKind::kClassMember; + member->location = loc; + member->node_type_name = "class_member"; + member->access_modifier = current_access; + + auto method = ParseMethodDeclaration(node, ctx); + member->member = std::move(method); + + ClassMemberParseResult result; + result.member = std::move(member); + results.push_back(std::move(result)); + } + else if (node_type == "property_declaration") + { + auto member = MakeNode(); + member->kind = NodeKind::kClassMember; + member->location = loc; + member->node_type_name = "class_member"; + member->access_modifier = current_access; + + auto prop = ParsePropertyDeclaration(node, ctx); + member->member = std::move(prop); + + ClassMemberParseResult result; + result.member = std::move(member); + results.push_back(std::move(result)); + } + + return results; + } + + StatementPtr ParseClassDefinition(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + auto class_def = MakeNode(); + class_def->kind = NodeKind::kClassDefinition; + class_def->location = loc; + class_def->node_type_name = "class_definition"; + + TSNode name_node = ts_node_child_by_field_name(node, "name", 4); + if (!ts_node_is_null(name_node)) + class_def->name = ts::Text(name_node, ctx.Source()); + + std::string name = "parent"; + uint32_t count = ts_node_child_count(node); + for (uint32_t i = 0; i < count; i++) + { + const char* field = ts_node_field_name_for_child(node, i); + if (!field || name != field) + continue; + TSNode parent_node = ts_node_child(node, i); + + std::string parent_name; + std::string_view parent_type = ts_node_type(parent_node); + + if (parent_type == "attribute") + parent_name = ts::Text(parent_node, ctx.Source()); + else + parent_name = ts::Text(parent_node, ctx.Source()); + + class_def->parent_classes.push_back(parent_name); + } + + TSNode body_node = ts_node_child_by_field_name(node, "body", 4); + if (!ts_node_is_null(body_node)) + { + AccessModifier current_access = AccessModifier::kPublic; + ReferenceModifier current_reference = ReferenceModifier::kNone; + + uint32_t count = ts_node_child_count(body_node); + for (uint32_t i = 0; i < count; i++) + { + TSNode member_node = ts_node_child(body_node, i); + if (!ts_node_is_named(member_node)) + continue; + if (ts::IsComment(member_node)) + continue; + + std::string member_type = ts_node_type(member_node); + if (member_type == "class_member") + { + uint32_t member_count = ts_node_child_count(member_node); + for (uint32_t j = 0; j < member_count; j++) + { + TSNode cm_child = ts_node_child(member_node, j); + + if (!ts_node_is_named(cm_child)) + continue; + + auto results = ParseClassMember(cm_child, ctx, current_access, current_reference); + for (auto& result : results) + { + if (result.access_modifier) + current_access = result.access_modifier.value(); + else if (result.reference_modifier) + current_reference = result.reference_modifier.value(); + else if (result.member) + class_def->members.push_back(std::move(result.member)); + } + } + } + else + { + auto results = ParseClassMember(member_node, ctx, current_access, current_reference); + for (auto& result : results) + { + if (result.access_modifier) + current_access = result.access_modifier.value(); + else if (result.reference_modifier) + current_reference = result.reference_modifier.value(); + else if (result.member) + class_def->members.push_back(std::move(result.member)); + } + } + } + } + + return class_def; + } + + StatementPtr ParseExternalMethodStatement(TSNode node, ParseContext& ctx) + { + Location loc = ts::NodeLocation(node); + + auto ext_method = MakeNode(); + ext_method->kind = NodeKind::kExternalMethodDefinition; + ext_method->location = loc; + ext_method->node_type_name = "external_method_definition"; + + TSNode class_node = ts_node_child_by_field_name(node, "class_name", 10); + if (!ts_node_is_null(class_node)) + ext_method->owner_class = ts::Text(class_node, ctx.Source()); + + TSNode op_node = ts_node_child_by_field_name(node, "operator", 8); + if (!ts_node_is_null(op_node)) + { + ext_method->is_operator_overload = true; + ext_method->operator_symbol = ts::Text(op_node, ctx.Source()); + } + else + { + TSNode method_node = ts_node_child_by_field_name(node, "method_name", 11); + if (!ts_node_is_null(method_node)) + ext_method->name = ts::Text(method_node, ctx.Source()); + } + + uint32_t count = ts_node_child_count(node); + for (uint32_t i = 0; i < count; i++) + { + TSNode child = ts_node_child(node, i); + if (!ts_node_is_named(child)) + continue; + + std::string_view child_type = ts_node_type(child); + if (child_type == "class") + { + ext_method->is_class_method = true; + break; + } + } + + ext_method->signature = ParseSignature(node, ctx); + + TSNode modifier_node = ts_node_child_by_field_name(node, "modifier", 8); + if (!ts_node_is_null(modifier_node)) + ext_method->modifier = ParseMethodModifier(modifier_node, ctx); + + TSNode body_node = ts_node_child_by_field_name(node, "body", 4); + if (!ts_node_is_null(body_node)) + ext_method->body = ParseStatement(body_node, ctx); + + if (utils::ToLower(ext_method->name) == "create") + ext_method->method_type = MethodType::kConstructor; + else if (utils::ToLower(ext_method->name) == "destroy") + ext_method->method_type = MethodType::kDestructor; + + return ext_method; + } +} diff --git a/lsp-server/src/language/ast/detail.hpp b/lsp-server/src/language/ast/detail.hpp new file mode 100644 index 0000000..817aa84 --- /dev/null +++ b/lsp-server/src/language/ast/detail.hpp @@ -0,0 +1,206 @@ +#pragma once + +#include "./types.hpp" +#include "./deserializer.hpp" +#include +#include + +extern "C" { +#include +} + +namespace lsp::language::ast::detail +{ + // ===== 统一的解析上下文 ===== + + class ParseContext + { + public: + ParseContext(const std::string& source, std::vector& errors) : + source_(source), errors_(errors) {} + + const std::string& Source() const { return source_; } + + std::vector& Errors() { return errors_; } + const std::vector& Errors() const { return errors_; } + + void RecordError(const Location& loc, const std::string& node_type, const std::string& message, ErrorSeverity severity = ErrorSeverity::Error) + { + errors_.push_back(ParseError{ loc, node_type, message, severity }); + } + + void RecordMissing(const Location& loc, const std::string& node_type) + { + RecordError(loc, node_type, "Syntax error: missing " + node_type); + } + + void RecordUnexpected(const Location& loc, const std::string& node_type, const std::string& context = "") + { + std::string msg = "Syntax error: unexpected token"; + if (!context.empty()) + msg += " in " + context; + RecordError(loc, node_type, msg); + } + + void RecordWarning(const Location& loc, const std::string& node_type, const std::string& message) + { + RecordError(loc, node_type, message, ErrorSeverity::Warning); + } + + template + std::unique_ptr ReportNullNode(const Location& loc, const std::string& expected_type) + { + RecordMissing(loc, expected_type); + return nullptr; + } + + template + std::unique_ptr ReportParseFailed(const Location& loc, const std::string& node_type, const std::string& reason = "") + { + std::string msg = "Failed to parse " + node_type; + if (!reason.empty()) + msg += ": " + reason; + RecordError(loc, node_type, msg); + return nullptr; + } + + private: + const std::string& source_; + std::vector& errors_; + }; + + // ===== 类成员解析结果 ===== + + struct ClassMemberParseResult + { + std::unique_ptr member; + std::optional access_modifier; + std::optional reference_modifier; + }; + + // ===== 语句解析器注册表 ===== + + class StatementParserRegistry + { + public: + using ParserFunc = std::function; + + static StatementParserRegistry& Instance() + { + static StatementParserRegistry instance; + return instance; + } + + void Register(const std::string& type, ParserFunc parser) + { + parsers_[type] = parser; + } + + ParserFunc Get(const std::string& type) const + { + auto it = parsers_.find(type); + return it != parsers_.end() ? it->second : nullptr; + } + + private: + StatementParserRegistry() = default; + StatementParserRegistry(const StatementParserRegistry&) = delete; + StatementParserRegistry& operator=(const StatementParserRegistry&) = delete; + + private: + std::unordered_map parsers_; + }; + + // ===== 初始化 ===== + void RegisterStatementParsers(); + + // ===== 操作符映射 ===== + BinaryOperator ParseBinaryOperator(const std::string& op_text); + UnaryOperator ParseUnaryOperator(const std::string& op_text); + AssignmentOperator ParseAssignmentOperator(const std::string& op_text); + + // ===== 基础辅助函数 ===== + TSNode FindChildByType(TSNode parent, const std::string& type); + bool IsSyntaxErrorNode(TSNode node); + std::vector CollectSyntaxErrors(TSNode node, const std::string& source); + + // 访问修饰符和方法修饰符解析 + AccessModifier ParseAccessModifier(TSNode node, ParseContext& ctx); + MethodModifier ParseMethodModifier(TSNode node, ParseContext& ctx); + ReferenceModifier ParseReferenceModifier(TSNode node, ParseContext& ctx); + + // 方法和属性声明解析 + std::unique_ptr ParseMethodDeclaration(TSNode node, ParseContext& ctx); + std::unique_ptr ParsePropertyDeclaration(TSNode node, ParseContext& ctx); + + // 类成员解析 + std::vector ParseClassMember(TSNode node, ParseContext& ctx, AccessModifier current_access, ReferenceModifier current_reference); + + // ===== 通用解析函数 ===== + Signature ParseSignature(TSNode node, ParseContext& ctx); + std::vector ParseParameters(TSNode params_node, ParseContext& ctx); + + // ===== 表达式解析 ===== + ExpressionPtr ParseExpression(TSNode node, ParseContext& ctx); + ExpressionPtr ParsePrimaryExpression(TSNode node, ParseContext& ctx); + ExpressionPtr ParseBinaryExpression(TSNode node, ParseContext& ctx); + ExpressionPtr ParseUnaryExpression(TSNode node, ParseContext& ctx); + ExpressionPtr ParseCallExpression(TSNode node, ParseContext& ctx); + ExpressionPtr ParseAttributeExpression(TSNode node, ParseContext& ctx); + ExpressionPtr ParseSubscriptExpression(TSNode node, ParseContext& ctx); + ExpressionPtr ParseArrayExpression(TSNode node, ParseContext& ctx); + ExpressionPtr ParseTernaryExpression(TSNode node, ParseContext& ctx); + ExpressionPtr ParseAssignmentExpression(TSNode node, ParseContext& ctx); + ExpressionPtr ParseAnonymousFunctionExpression(TSNode node, ParseContext& ctx); + ExpressionPtr ParseTSSQLExpression(TSNode node, ParseContext& ctx); + ExpressionPtr ParseEchoExpression(TSNode node, ParseContext& ctx); + ExpressionPtr ParseRaiseExpression(TSNode node, ParseContext& ctx); + ExpressionPtr ParseNewExpression(TSNode node, ParseContext& ctx); + ExpressionPtr ParseInheritedExpression(TSNode node, ParseContext& ctx); + + // ===== 左值解析 ===== + LeftHandSide ParseLeftHandSide(TSNode node, ParseContext& ctx); + std::unique_ptr ParseUnpackPattern(TSNode node, ParseContext& ctx); + + // ===== 语句解析 ===== + StatementPtr ParseUnitDefinition(TSNode node, ParseContext& ctx); + StatementPtr ParseStatement(TSNode node, ParseContext& ctx); + StatementPtr ParseSingleSuite(TSNode node, ParseContext& ctx); + StatementPtr ParseBlockSuite(TSNode node, ParseContext& ctx); + StatementPtr ParseExpressionStatement(TSNode node, ParseContext& ctx); + StatementPtr ParseAssignmentStatement(TSNode node, ParseContext& ctx); + StatementPtr ParseVarStatement(TSNode node, ParseContext& ctx); + StatementPtr ParseStaticStatement(TSNode node, ParseContext& ctx); + StatementPtr ParseGlobalStatement(TSNode node, ParseContext& ctx); + StatementPtr ParseConstStatement(TSNode node, ParseContext& ctx); + StatementPtr ParseIfStatement(TSNode node, ParseContext& ctx); + StatementPtr ParseForInStatement(TSNode node, ParseContext& ctx); + StatementPtr ParseForToStatement(TSNode node, ParseContext& ctx); + StatementPtr ParseWhileStatement(TSNode node, ParseContext& ctx); + StatementPtr ParseRepeatStatement(TSNode node, ParseContext& ctx); + StatementPtr ParseCaseStatement(TSNode node, ParseContext& ctx); + StatementPtr ParseTryStatement(TSNode node, ParseContext& ctx); + StatementPtr ParseBreakStatement(TSNode node, ParseContext& ctx); + StatementPtr ParseContinueStatement(TSNode node, ParseContext& ctx); + StatementPtr ParseReturnStatement(TSNode node, ParseContext& ctx); + StatementPtr ParseUsesStatement(TSNode node, ParseContext& ctx); + StatementPtr ParseInheritedStatement(TSNode node, ParseContext& ctx); + StatementPtr ParseFunctionDefinition(TSNode node, ParseContext& ctx); + StatementPtr ParseFunctionDeclaration(TSNode node, ParseContext& ctx); + StatementPtr ParseClassDefinition(TSNode node, ParseContext& ctx); + StatementPtr ParseExternalMethodStatement(TSNode node, ParseContext& ctx); + StatementPtr ParseMatrixIterationStatement(TSNode node, ParseContext& ctx); + + // ===== TSLX 模板解析 ===== + StatementPtr ParseTSLXOpenTag(TSNode node, ParseContext& ctx); + StatementPtr ParseTSLXCloseTag(TSNode node, ParseContext& ctx); + StatementPtr ParseTSLXOutputTag(TSNode node, ParseContext& ctx); + StatementPtr ParseTSLXExpressionTag(TSNode node, ParseContext& ctx); + StatementPtr ParseHTMLSelfClosingTag(TSNode node, ParseContext& ctx); + StatementPtr ParseHTMLPairedTag(TSNode node, ParseContext& ctx); + StatementPtr ParseHTMLComment(TSNode node, ParseContext& ctx); + + // ===== 通用声明解析模板 ===== + template + StatementPtr ParseDeclarationStatement(TSNode node, ParseContext& ctx, NodeKind decl_kind, NodeKind stmt_kind, const std::string& keyword); +} diff --git a/lsp-server/src/language/ast/token_collector.cpp b/lsp-server/src/language/ast/token_collector.cpp new file mode 100644 index 0000000..5873bbd --- /dev/null +++ b/lsp-server/src/language/ast/token_collector.cpp @@ -0,0 +1,312 @@ +#include "./token_collector.hpp" +#include "./tree_sitter_utils.hpp" + +namespace lsp::language::ast +{ + // ===== TokenCollector 实现 ===== + + TokenCollector::TokenCollector(const TokenCollectionOptions& options) : + options_(options) + { + } + + std::vector TokenCollector::Collect(TSNode root, const std::string& source) + { + std::vector tokens; + TSNode null_parent = { 0 }; + CollectRecursive(root, source, tokens, 0, null_parent); + return tokens; + } + + std::vector TokenCollector::CollectByType( + TSNode root, + const std::string& source, + const std::vector& types) + { + // 临时修改选项以仅包含指定类型 + TokenCollectionOptions original_options = options_; + options_.include_types = std::unordered_set(types.begin(), types.end()); + + auto result = Collect(root, source); + + // 恢复原始选项 + options_ = original_options; + + return result; + } + + std::vector TokenCollector::CollectInRange( + TSNode root, + const std::string& source, + uint32_t start_line, + uint32_t end_line) + { + // 临时修改选项以包含位置过滤 + TokenCollectionOptions original_options = options_; + options_.has_location_filter = true; + options_.filter_start_line = start_line; + options_.filter_end_line = end_line; + + auto result = Collect(root, source); + + // 恢复原始选项 + options_ = original_options; + + return result; + } + + std::vector TokenCollector::CollectLeafNodes(TSNode root, const std::string& source) + { + auto all_tokens = Collect(root, source); + std::vector leaf_tokens; + + for (const auto& token : all_tokens) + { + // 叶子节点的特征:文本长度等于字节范围 + // 或者可以通过重新检查 TSNode 来确定 + leaf_tokens.push_back(token); + } + + return leaf_tokens; + } + + std::vector TokenCollector::FindTokensAtPosition(TSNode root, const std::string& source, uint32_t line, uint32_t column) + { + auto all_tokens = Collect(root, source); + std::vector result; + + for (const auto& token : all_tokens) + { + const auto& loc = token.location; + // 检查位置是否在 token 范围内 + if (loc.start_line <= line && line <= loc.end_line) + { + if (line == loc.start_line && line == loc.end_line) + { + if (loc.start_column <= column && column <= loc.end_column) + result.push_back(token); + } + else if (line == loc.start_line) + { + if (column >= loc.start_column) + result.push_back(token); + } + else if (line == loc.end_line) + { + if (column <= loc.end_column) + result.push_back(token); + } + else + { + result.push_back(token); + } + } + } + + return result; + } + + std::vector TokenCollector::FindTokensByText(TSNode root, const std::string& source, const std::string& text, bool exact_match) + { + auto all_tokens = Collect(root, source); + std::vector result; + + for (const auto& token : all_tokens) + { + if (exact_match) + { + if (token.text == text) + result.push_back(token); + } + else + { + if (token.text.find(text) != std::string::npos) + result.push_back(token); + } + } + + return result; + } + + std::vector TokenCollector::FindTokensBy(TSNode root, const std::string& source, std::function predicate) + { + auto all_tokens = Collect(root, source); + std::vector result; + + for (const auto& token : all_tokens) + { + if (predicate(token)) + result.push_back(token); + } + + return result; + } + + uint32_t TokenCollector::CountTokensByType(TSNode root, const std::string& source, const std::string& type) + { + auto tokens = CollectByType(root, source, { type }); + return tokens.size(); + } + + std::vector TokenCollector::GetUniqueTypes(TSNode root, const std::string& source) + { + auto tokens = Collect(root, source); + std::unordered_set unique_types; + + for (const auto& token : tokens) + { + unique_types.insert(token.type); + } + + return std::vector(unique_types.begin(), unique_types.end()); + } + + // ===== 私有方法实现 ===== + + void TokenCollector::CollectRecursive(TSNode node, const std::string& source, std::vector& tokens, uint32_t depth, TSNode parent) + { + // 检查深度限制 + if (depth > options_.max_depth || depth < options_.min_depth) + return; + + // 创建 TokenInfo + TokenInfo info; + FillTokenInfo(info, node, source, depth, parent); + + // 检查是否应该收集此节点 + if (ShouldCollectNode(info)) + { + tokens.push_back(info); + } + + // 递归处理子节点 + uint32_t child_count = ts_node_child_count(node); + for (uint32_t i = 0; i < child_count; ++i) + { + TSNode child = ts_node_child(node, i); + CollectRecursive(child, source, tokens, depth + 1, node); + } + } + + bool TokenCollector::ShouldCollectNode(const TokenInfo& info) const + { + // 检查命名节点过滤 + if (!options_.include_anonymous && !info.is_named) + return false; + + // 检查注释过滤 + if (!options_.include_comments && IsCommentNode(info.type)) + return false; + + // 检查空白过滤 + if (!options_.include_whitespace && IsWhitespaceNode(info.type)) + return false; + + // 检查错误节点过滤 + if (!options_.include_errors && info.is_error) + return false; + + // 检查缺失节点过滤 + if (!options_.include_missing && info.is_missing) + return false; + + // 检查类型包含过滤 + if (!options_.include_types.empty()) + { + if (options_.include_types.find(info.type) == options_.include_types.end()) + return false; + } + + // 检查类型排除过滤 + if (!options_.exclude_types.empty()) + { + if (options_.exclude_types.find(info.type) != options_.exclude_types.end()) + return false; + } + + // 检查空文本过滤 + if (options_.skip_empty_text && info.text.empty()) + return false; + + // 检查文本长度过滤 + uint32_t text_len = info.text.length(); + if (text_len < options_.min_text_length || text_len > options_.max_text_length) + return false; + + // 检查位置过滤 + if (options_.has_location_filter && !IsLocationInRange(info.location)) + return false; + + // 检查自定义过滤器 + if (options_.custom_filter && !options_.custom_filter(info)) + return false; + + return true; + } + + void TokenCollector::FillTokenInfo(TokenInfo& info, TSNode node, const std::string& source, uint32_t depth, TSNode parent) const + { + // 基本信息 + info.location = ts::NodeLocation(node); + info.type = ts_node_type(node); + info.text = ts::Text(node, source); + info.is_named = ts_node_is_named(node); + info.depth = depth; + + // 错误和缺失标记 + info.is_error = ts_node_is_error(node); + info.is_missing = ts_node_is_missing(node); + + // 父节点信息 + if (!ts_node_is_null(parent)) + { + info.parent_type = ts_node_type(parent); + + // 查找当前节点在父节点中的索引 + uint32_t sibling_count = ts_node_child_count(parent); + info.sibling_count = sibling_count; + + for (uint32_t i = 0; i < sibling_count; ++i) + { + TSNode sibling = ts_node_child(parent, i); + if (ts_node_eq(sibling, node)) + { + info.child_index = i; + break; + } + } + } + } + + bool TokenCollector::IsCommentNode(const std::string& type) const + { + return type == "line_comment" || + type == "block_comment" || + type == "nested_comment" || + type == "comment"; + } + + bool TokenCollector::IsWhitespaceNode(const std::string& type) const + { + return type == "whitespace" || + type == " " || + type == "\n" || + type == "\r" || + type == "\t"; + } + + bool TokenCollector::IsLocationInRange(const Location& loc) const + { + if (!options_.has_location_filter) + return true; + + // 检查范围是否有重叠 + if (loc.end_line < options_.filter_start_line) + return false; + if (loc.start_line > options_.filter_end_line) + return false; + + return true; + } + +} diff --git a/lsp-server/src/language/ast/token_collector.hpp b/lsp-server/src/language/ast/token_collector.hpp new file mode 100644 index 0000000..e6179e1 --- /dev/null +++ b/lsp-server/src/language/ast/token_collector.hpp @@ -0,0 +1,153 @@ +#pragma once + +#include +#include +#include +#include +#include "./types.hpp" + +extern "C" { +#include +} + +namespace lsp::language::ast +{ + struct TokenInfo + { + Location location; + std::string type; // 节点类型 (如 "identifier", "number") + std::string text; // Token 文本内容 + bool is_named = false; + uint32_t depth = 0; + + std::string parent_type; // 父节点类型 + uint32_t child_index = 0; // 在父节点中的索引 + uint32_t sibling_count = 0; // 兄弟节点总数 + + bool is_error = false; // 是否是错误节点 + bool is_missing = false; // 是否是缺失节点 + }; + + // ===== Token 收集选项 ===== + + struct TokenCollectionOptions + { + // 基本过滤选项 + bool include_anonymous = true; // 包含匿名节点 (如括号、分号等) + bool include_comments = false; // 包含注释节点 + bool include_whitespace = false; // 包含空白节点 + bool include_errors = true; // 包含错误节点 + bool include_missing = true; // 包含缺失节点 + + // 深度控制 + uint32_t max_depth = UINT32_MAX; // 最大遍历深度 + uint32_t min_depth = 0; // 最小遍历深度 + + // 类型过滤 + std::unordered_set include_types; // 仅包含这些类型 (为空则包含所有) + std::unordered_set exclude_types; // 排除这些类型 + + // 文本过滤 + bool skip_empty_text = false; // 跳过空文本节点 + uint32_t min_text_length = 0; // 最小文本长度 + uint32_t max_text_length = UINT32_MAX; // 最大文本长度 + + // 位置过滤 + bool has_location_filter = false; // 是否启用位置过滤 + uint32_t filter_start_line = 0; // 过滤起始行 + uint32_t filter_end_line = UINT32_MAX; // 过滤结束行 + + // 自定义过滤器 + std::function custom_filter; + + TokenCollectionOptions() = default; + + // 便捷构造函数 + static TokenCollectionOptions OnlyNamed() + { + TokenCollectionOptions opts; + opts.include_anonymous = false; + return opts; + } + + static TokenCollectionOptions WithComments() + { + TokenCollectionOptions opts; + opts.include_comments = true; + return opts; + } + + static TokenCollectionOptions OnlyTypes(const std::vector& types) + { + TokenCollectionOptions opts; + opts.include_types = std::unordered_set(types.begin(), types.end()); + return opts; + } + + static TokenCollectionOptions ExcludeTypes(const std::vector& types) + { + TokenCollectionOptions opts; + opts.exclude_types = std::unordered_set(types.begin(), types.end()); + return opts; + } + + static TokenCollectionOptions InRange(uint32_t start_line, uint32_t end_line) + { + TokenCollectionOptions opts; + opts.has_location_filter = true; + opts.filter_start_line = start_line; + opts.filter_end_line = end_line; + return opts; + } + }; + + // ===== Token 收集器类 ===== + + class TokenCollector + { + public: + explicit TokenCollector(const TokenCollectionOptions& options = {}); + ~TokenCollector() = default; + TokenCollector(const TokenCollector&) = delete; + TokenCollector& operator=(const TokenCollector&) = delete; + TokenCollector(TokenCollector&&) = default; + TokenCollector& operator=(TokenCollector&&) = default; + + std::vector Collect(TSNode root, const std::string& source); + std::vector CollectByType(TSNode root, const std::string& source, const std::vector& types); + std::vector CollectInRange(TSNode root, const std::string& source, uint32_t start_line, uint32_t end_line); + std::vector CollectLeafNodes(TSNode root, const std::string& source); + + std::vector FindTokensAtPosition(TSNode root, const std::string& source, uint32_t line, uint32_t column); + std::vector FindTokensByText(TSNode root, const std::string& source, const std::string& text, bool exact_match = true); + std::vector FindTokensBy(TSNode root, const std::string& source, std::function predicate); + + uint32_t CountTokensByType(TSNode root, const std::string& source, const std::string& type); + std::vector GetUniqueTypes(TSNode root, const std::string& source); + + void SetOptions(const TokenCollectionOptions& options) { options_ = options; } + const TokenCollectionOptions& GetOptions() const { return options_; } + + private: + void CollectRecursive(TSNode node, const std::string& source, std::vector& tokens, uint32_t depth, TSNode parent); + bool ShouldCollectNode(const TokenInfo& info) const; + void FillTokenInfo(TokenInfo& info, TSNode node, const std::string& source, uint32_t depth, TSNode parent) const; + bool IsCommentNode(const std::string& type) const; + bool IsWhitespaceNode(const std::string& type) const; + bool IsLocationInRange(const Location& loc) const; + + private: + TokenCollectionOptions options_; + }; + + inline std::vector CollectNamedTokens(TSNode root, const std::string& source) + { + return TokenCollector(TokenCollectionOptions::OnlyNamed()).Collect(root, source); + } + + inline std::vector CollectTokensOfType(TSNode root, const std::string& source, const std::string& type) + { + return TokenCollector().CollectByType(root, source, { type }); + } + +} diff --git a/lsp-server/src/language/ast/tree_sitter_utils.cpp b/lsp-server/src/language/ast/tree_sitter_utils.cpp index 2d52def..588bf2e 100644 --- a/lsp-server/src/language/ast/tree_sitter_utils.cpp +++ b/lsp-server/src/language/ast/tree_sitter_utils.cpp @@ -2,51 +2,22 @@ namespace lsp::language::ast::ts { - // ==================== 字符串池实现 ==================== - - StringPool& StringPool::Instance() - { - static StringPool instance; - return instance; - } - - std::string_view StringPool::Intern(std::string_view str) - { - auto it = pool_.find(std::string(str)); - if (it != pool_.end()) - { - return *it; - } - - auto [inserted_it, _] = pool_.insert(std::string(str)); - return *inserted_it; - } - - void StringPool::Clear() - { - pool_.clear(); - } - - // ==================== 文本提取 ==================== - - std::string Text(TSNode node, std::string_view source) + std::string Text(TSNode node, const std::string& source) { uint32_t start = ts_node_start_byte(node); uint32_t end = ts_node_end_byte(node); - if (start >= source.length() || end > source.length() || start >= end) - return ""; - return std::string(source.substr(start, end - start)); - } - std::string Text(TSNode node, const std::string& source) - { - return Text(node, std::string_view(source)); + if (start >= end || end > source.length()) + return ""; + + return source.substr(start, end - start); } Location NodeLocation(TSNode node) { TSPoint start = ts_node_start_point(node); TSPoint end = ts_node_end_point(node); + return Location{ static_cast(start.row), static_cast(start.column), @@ -57,84 +28,4 @@ namespace lsp::language::ast::ts }; } - std::string FieldText(TSNode node, std::string_view field_name, std::string_view source) - { - TSNode field = FieldChild(node, field_name); - return IsNull(field) ? "" : Text(field, source); - } - - std::string FieldText(TSNode node, std::string_view field_name, const std::string& source) - { - return FieldText(node, field_name, std::string_view(source)); - } - - std::vector Children(TSNode node) - { - std::vector children; - uint32_t count = ts_node_child_count(node); - children.reserve(count); - for (uint32_t i = 0; i < count; i++) - children.push_back(ts_node_child(node, i)); - return children; - } - - std::vector FieldChildren(TSNode node, std::string_view field_name) - { - std::vector result; - uint32_t count = ts_node_child_count(node); - for (uint32_t i = 0; i < count; i++) - { - const char* field = ts_node_field_name_for_child(node, i); - if (field && field_name == field) - result.push_back(ts_node_child(node, i)); - } - return result; - } - - std::vector ChildSummaries(TSNode node, std::string_view source) - { - std::vector result; - uint32_t count = ts_node_child_count(node); - for (uint32_t i = 0; i < count; i++) - { - TSNode child = ts_node_child(node, i); - const char* field_name = ts_node_field_name_for_child(node, i); - result.push_back(NodeSummary{ - .node = child, - .field = field_name ? field_name : "", - .type = std::string(Type(child)), - .text = Text(child, source) }); - } - return result; - } - - std::vector ChildSummaries(TSNode node, const std::string& source) - { - return ChildSummaries(node, std::string_view(source)); - } - - std::vector FieldSummaries(TSNode node, std::string_view field_name, std::string_view source) - { - std::vector result; - uint32_t count = ts_node_child_count(node); - for (uint32_t i = 0; i < count; i++) - { - TSNode child = ts_node_child(node, i); - const char* field = ts_node_field_name_for_child(node, i); - if (field && field_name == field) - { - result.push_back(NodeSummary{ - .node = child, - .field = field, - .type = std::string(Type(child)), - .text = Text(child, source) }); - } - } - return result; - } - - std::vector FieldSummaries(TSNode node, std::string_view field_name, const std::string& source) - { - return FieldSummaries(node, field_name, std::string_view(source)); - } } diff --git a/lsp-server/src/language/ast/tree_sitter_utils.hpp b/lsp-server/src/language/ast/tree_sitter_utils.hpp index 24bfef7..2e2a30d 100644 --- a/lsp-server/src/language/ast/tree_sitter_utils.hpp +++ b/lsp-server/src/language/ast/tree_sitter_utils.hpp @@ -1,8 +1,5 @@ #pragma once #include -#include -#include -#include #include "./types.hpp" extern "C" { @@ -11,94 +8,16 @@ extern "C" { namespace lsp::language::ast::ts { - class StringPool - { - public: - static StringPool& Instance(); - - // 缓存字符串,返回池中的引用 - std::string_view Intern(std::string_view str); - - void Clear(); - size_t Size() const { return pool_.size(); } - - private: - StringPool() = default; - StringPool(const StringPool&) = delete; - StringPool& operator=(const StringPool&) = delete; - - private: - std::unordered_set pool_; - }; - - // ==================== 节点摘要 ==================== - - struct NodeSummary - { - TSNode node; - std::string field; - std::string type; - std::string text; - }; - - // ==================== 基础查询 ==================== - - // 获取节点文本(使用 string_view 优化) - std::string Text(TSNode node, std::string_view source); std::string Text(TSNode node, const std::string& source); - // 获取节点类型(使用字符串池) - inline std::string_view Type(TSNode node); - - // 获取节点位置 Location NodeLocation(TSNode node); - // 节点状态检查 - inline bool IsNull(TSNode node); - inline bool IsComment(TSNode node); - - // ==================== 字段操作 ==================== - - inline TSNode FieldChild(TSNode node, std::string_view field_name); - std::string FieldText(TSNode node, std::string_view field_name, std::string_view source); - std::string FieldText(TSNode node, std::string_view field_name, const std::string& source); - inline bool HasField(TSNode node, std::string_view field_name); - - // ==================== 子节点操作 ==================== - - std::vector Children(TSNode node); - std::vector FieldChildren(TSNode node, std::string_view field_name); - std::vector ChildSummaries(TSNode node, std::string_view source); - std::vector ChildSummaries(TSNode node, const std::string& source); - std::vector FieldSummaries(TSNode node, std::string_view field_name, std::string_view source); - std::vector FieldSummaries(TSNode node, std::string_view field_name, const std::string& source); - - // ==================== Inline 实现 ==================== - - inline std::string_view Type(TSNode node) - { - const char* type_str = ts_node_type(node); - return StringPool::Instance().Intern(type_str); - } - - inline bool IsNull(TSNode node) - { - return ts_node_is_null(node); - } - inline bool IsComment(TSNode node) { - std::string_view type = Type(node); - return type == "line_comment" || type == "block_comment" || type == "nested_comment"; + std::string_view type = ts_node_type(node); + return type == "line_comment" || + type == "block_comment" || + type == "nested_comment"; } - inline TSNode FieldChild(TSNode node, std::string_view field_name) - { - return ts_node_child_by_field_name(node, field_name.data(), field_name.length()); - } - - inline bool HasField(TSNode node, std::string_view field_name) - { - return !IsNull(FieldChild(node, field_name)); - } } diff --git a/lsp-server/src/language/ast/types.hpp b/lsp-server/src/language/ast/types.hpp index b54873f..f88eb44 100644 --- a/lsp-server/src/language/ast/types.hpp +++ b/lsp-server/src/language/ast/types.hpp @@ -2,15 +2,14 @@ #include #include +#include #include -#include #include -#include +#include namespace lsp::language::ast { - // ==================== 基础类型 ==================== - + // ===== 基础类型 ===== struct Location { uint32_t start_line = 0; @@ -21,28 +20,868 @@ namespace lsp::language::ast uint32_t end_byte = 0; }; - struct Node + // ===== 节点类型枚举 ===== + enum class NodeKind { - Location location; - std::string node_type; + // Expressions + kIdentifier, + kLiteral, + kBinaryExpression, + kUnaryExpression, + kTernaryExpression, + kCallExpression, + kAttributeExpression, + kSubscriptExpression, + kArrayExpression, + kAnonymousFunctionExpression, + kPrefixIncrementExpression, + kPrefixDecrementExpression, + kPostfixIncrementExpression, + kPostfixDecrementExpression, + kFunctionPointerExpression, + kComparisonExpression, + + // Assignment Expressions + kAssignmentExpression, + kAugmentedAssignmentExpression, + + // Statements + kExpressionStatement, + kVarStatement, + kStaticStatement, + kGlobalStatement, + kConstStatement, + kAssignmentStatement, + kBlockStatement, + kIfStatement, + kForInStatement, + kForToStatement, + kWhileStatement, + kRepeatStatement, + kCaseStatement, + kTryStatement, + kBreakStatement, + kContinueStatement, + kReturnStatement, + kUsesStatement, + kInheritedStatement, + + // Declarations + kVarDeclaration, + kStaticDeclaration, + kGlobalDeclaration, + kFieldDeclaration, + kFunctionDeclaration, + kFunctionDefinition, + kClassDefinition, + kMethodDeclaration, + kPropertyDeclaration, + kExternalMethodDefinition, + kUnitDefinition, + + // TSSQL 节点 + kTSSQLSelectExpression, + kTSSQLUpdateExpression, + kTSSQLDeleteExpression, + kTSSQLInsertExpression, + + // Special + kParameter, + kUnpackPattern, + kCaseBranch, + kClassMember, }; - struct Expression + // ===== 枚举类型 ===== + enum class LiteralKind { + kNumber, + kString, + kBoolean, + kNil, + kInfinity, + kEllipsis + }; + + enum class BinaryOperator + { + kAdd, + kSubtract, + kMultiply, + kDivide, + kIntDivide, + kModulo, + kPower, + kLogarithm, + kEqual, + kNotEqual, + kGreater, + kGreaterEqual, + kLess, + kLessEqual, + kDotEqual, + kDotNotEqual, + kDotGreater, + kDotGreaterEqual, + kDotLess, + kDotLessEqual, + kLike, + kIs, + kIn, + kLogicalOr, + kLogicalAnd, + kDotLogicalOr, + kDotLogicalAnd, + kBitwiseOr, + kBitwiseAnd, + kBitwiseXor, + kDotBitwiseOr, + kDotBitwiseAnd, + kDotBitwiseXor, + kShl, + kShr, + kRol, + kRor, + kMatrixMultiply, + kMatrixDivide, + kMatrixIntDivide, + kMatrixPower, + kMatrixConcat, + kMatrixConcatVertical, + kUnion, + kUnion2, + kIntersect, + kOutersect, + kMinus, + kConcatenation, + kRange, + }; + + enum class UnaryOperator + { + kPlus, + kMinus, + kNot, + kBitwiseNot, + kDotNot, + kMatrixTranspose, + kDerivative, + kExprAt, + kExprRef, + }; + + enum class AssignmentOperator + { + kAssign, + kAddAssign, + kSubtractAssign, + kMultiplyAssign, + kDivideAssign, + kIntDivideAssign, + kPowerAssign, + kLogarithmAssign, + kModuloAssign, + kDivAssign, + kBitwiseOrAssign, + kBitwiseAndAssign, + kMatrixMultiplyAssign, + kMatrixDivideAssign, + kMatrixIntDivideAssign, + kMatrixPowerAssign, + kMatrixConcatAssign, + kConcatAssign, + kDotBitwiseOrAssign, + kDotBitwiseAndAssign, + kDotLogicalOrAssign, + kDotLogicalAndAssign, + kDotBitwiseXorAssign, + kUnionAssign, + kUnion2Assign, + kIntersectAssign, + kOutersectAssign, + kMinusAssign, + }; + + enum class AccessModifier + { + kPublic, + kProtected, + kPrivate + }; + + enum class ReferenceModifier + { + kNone, + kWeakRef, + kAutoRef + }; + + enum class MethodModifier + { + kNone, + kVirtual, + kOverride, + kOverload + }; + + enum class MethodType + { + kNormal, + kConstructor, + kDestructor + }; + + enum class TSSQLExpressionType + { + kSelect, + kSSelect, + kVSelect, + kMSelect, + kUpdate, + kDelete, + kInsert + }; + + // ===== 前向声明 ===== + class ASTNode; + class Expression; + class Statement; + class Declaration; + class ASTVisitor; + + class Identifier; + class Literal; + class BinaryExpression; + class UnaryExpression; + class TernaryExpression; + class CallExpression; + class AttributeExpression; + class SubscriptExpression; + class ArrayExpression; + class AnonymousFunctionExpression; + class PrefixIncrementExpression; + class PrefixDecrementExpression; + class PostfixIncrementExpression; + class PostfixDecrementExpression; + class FunctionPointerExpression; + class AssignmentExpression; + class ComparisonExpression; + class ExpressionStatement; + class VarStatement; + class StaticStatement; + class GlobalStatement; + class ConstStatement; + class AssignmentStatement; + class BlockStatement; + class IfStatement; + class ForInStatement; + class ForToStatement; + class WhileStatement; + class RepeatStatement; + class CaseStatement; + class TryStatement; + class BreakStatement; + class ContinueStatement; + class ReturnStatement; + class UsesStatement; + class FunctionDefinition; + class FunctionDeclaration; + class VarDeclaration; + class StaticDeclaration; + class GlobalDeclaration; + class FieldDeclaration; + class UnpackPattern; + class MethodDeclaration; + class ExternalMethodDefinition; + class PropertyDeclaration; + class ClassMember; + class ClassDefinition; + class UnitDefinition; + class TSSQLExpression; + + using ASTNodePtr = std::unique_ptr; + using ExpressionPtr = std::unique_ptr; + using StatementPtr = std::unique_ptr; + using DeclarationPtr = std::unique_ptr; + + // ===== 访问者接口 ===== + class ASTVisitor + { + public: + virtual ~ASTVisitor() = default; + + virtual void VisitUnitDefinition(UnitDefinition& node) = 0; + virtual void VisitMethodDeclaration(MethodDeclaration& node) = 0; + virtual void VisitPropertyDeclaration(PropertyDeclaration& node) = 0; + virtual void VisitClassMember(ClassMember& node) = 0; + virtual void VisitClassDefinition(ClassDefinition& node) = 0; + virtual void VisitExternalMethodDefinition(ExternalMethodDefinition& node) = 0; + virtual void VisitIdentifier(Identifier& node) = 0; + virtual void VisitLiteral(Literal& node) = 0; + virtual void VisitBinaryExpression(BinaryExpression& node) = 0; + virtual void VisitUnaryExpression(UnaryExpression& node) = 0; + virtual void VisitTernaryExpression(TernaryExpression& node) = 0; + virtual void VisitCallExpression(CallExpression& node) = 0; + virtual void VisitAttributeExpression(AttributeExpression& node) = 0; + virtual void VisitSubscriptExpression(SubscriptExpression& node) = 0; + virtual void VisitArrayExpression(ArrayExpression& node) = 0; + virtual void VisitAnonymousFunctionExpression(AnonymousFunctionExpression& node) = 0; + virtual void VisitPrefixIncrementExpression(PrefixIncrementExpression& node) = 0; + virtual void VisitPrefixDecrementExpression(PrefixDecrementExpression& node) = 0; + virtual void VisitPostfixIncrementExpression(PostfixIncrementExpression& node) = 0; + virtual void VisitPostfixDecrementExpression(PostfixDecrementExpression& node) = 0; + virtual void VisitFunctionPointerExpression(FunctionPointerExpression& node) = 0; + virtual void VisitAssignmentExpression(AssignmentExpression& node) = 0; + virtual void VisitComparisonExpression(ComparisonExpression& node) = 0; + virtual void VisitExpressionStatement(ExpressionStatement& node) = 0; + virtual void VisitVarStatement(VarStatement& node) = 0; + virtual void VisitStaticStatement(StaticStatement& node) = 0; + virtual void VisitGlobalStatement(GlobalStatement& node) = 0; + virtual void VisitConstStatement(ConstStatement& node) = 0; + virtual void VisitAssignmentStatement(AssignmentStatement& node) = 0; + virtual void VisitBlockStatement(BlockStatement& node) = 0; + virtual void VisitIfStatement(IfStatement& node) = 0; + virtual void VisitForInStatement(ForInStatement& node) = 0; + virtual void VisitForToStatement(ForToStatement& node) = 0; + virtual void VisitWhileStatement(WhileStatement& node) = 0; + virtual void VisitRepeatStatement(RepeatStatement& node) = 0; + virtual void VisitCaseStatement(CaseStatement& node) = 0; + virtual void VisitTryStatement(TryStatement& node) = 0; + virtual void VisitBreakStatement(BreakStatement& node) = 0; + virtual void VisitContinueStatement(ContinueStatement& node) = 0; + virtual void VisitReturnStatement(ReturnStatement& node) = 0; + virtual void VisitUsesStatement(UsesStatement& node) = 0; + virtual void VisitFunctionDefinition(FunctionDefinition& node) = 0; + virtual void VisitFunctionDeclaration(FunctionDeclaration& node) = 0; + virtual void VisitVarDeclaration(VarDeclaration& node) = 0; + virtual void VisitStaticDeclaration(StaticDeclaration& node) = 0; + virtual void VisitGlobalDeclaration(GlobalDeclaration& node) = 0; + virtual void VisitFieldDeclaration(FieldDeclaration& node) = 0; + virtual void VisitTSSQLExpression(TSSQLExpression& node) = 0; + virtual void VisitUnpackPattern(UnpackPattern& node) = 0; + }; + + // ===== 基类 ASTNode ===== + class ASTNode + { + public: + virtual ~ASTNode() = default; + virtual void Accept(ASTVisitor& visitor) = 0; + + public: + NodeKind kind; Location location; - std::string node_type; - std::string text; + std::string node_type_name; + }; + + // ===== Expression 基类 ===== + class Expression : public ASTNode + { + public: + virtual ~Expression() = default; + virtual std::optional TypeHint() const { return std::nullopt; } + }; + + // ===== 具体节点类型 ===== + + class Identifier : public Expression + { + public: + Identifier() { kind = NodeKind::kIdentifier; } + void Accept(ASTVisitor& visitor) override { visitor.VisitIdentifier(*this); } + + public: + std::string name; + }; + + class Literal : public Expression + { + public: + Literal() { kind = NodeKind::kLiteral; } + void Accept(ASTVisitor& visitor) override { visitor.VisitLiteral(*this); } + + public: + LiteralKind literal_kind; + std::string value; + }; + + class BinaryExpression : public Expression + { + public: + BinaryExpression() { kind = NodeKind::kBinaryExpression; } + void Accept(ASTVisitor& visitor) override { visitor.VisitBinaryExpression(*this); } + + public: + BinaryOperator op; + ExpressionPtr left; + ExpressionPtr right; + }; + + class ComparisonExpression : public Expression + { + public: + struct Comparison + { + BinaryOperator op; + ExpressionPtr right; + }; + + ComparisonExpression() { kind = NodeKind::kComparisonExpression; } + void Accept(ASTVisitor& visitor) override { visitor.VisitComparisonExpression(*this); } + + public: + ExpressionPtr left; + std::vector comparisons; + }; + + class UnaryExpression : public Expression + { + public: + UnaryExpression() { kind = NodeKind::kUnaryExpression; } + void Accept(ASTVisitor& visitor) override { visitor.VisitUnaryExpression(*this); } + + public: + UnaryOperator op; + ExpressionPtr argument; + }; + + class TernaryExpression : public Expression + { + public: + TernaryExpression() { kind = NodeKind::kTernaryExpression; } + void Accept(ASTVisitor& visitor) override { visitor.VisitTernaryExpression(*this); } + + public: + ExpressionPtr condition; + ExpressionPtr consequence; + ExpressionPtr alternative; + }; + + class CallExpression : public Expression + { + public: + struct Argument + { + std::optional name; + ExpressionPtr value; + bool is_spread = false; + }; + + CallExpression() { kind = NodeKind::kCallExpression; } + void Accept(ASTVisitor& visitor) override { visitor.VisitCallExpression(*this); } + + public: + ExpressionPtr callee; + std::vector arguments; + }; + + class AttributeExpression : public Expression + { + public: + AttributeExpression() { kind = NodeKind::kAttributeExpression; } + void Accept(ASTVisitor& visitor) override { visitor.VisitAttributeExpression(*this); } + + public: + ExpressionPtr object; + std::string attribute; + }; + + class SubscriptExpression : public Expression + { + public: + struct Index + { + ExpressionPtr start; + ExpressionPtr end; + ExpressionPtr step; + bool is_slice = false; + bool is_empty_slice = false; + }; + + SubscriptExpression() { kind = NodeKind::kSubscriptExpression; } + void Accept(ASTVisitor& visitor) override { visitor.VisitSubscriptExpression(*this); } + + public: + ExpressionPtr value; + std::vector indices; + }; + + class ArrayExpression : public Expression + { + public: + struct Element + { + ExpressionPtr key; + ExpressionPtr value; + bool is_nested = false; + }; + + ArrayExpression() { kind = NodeKind::kArrayExpression; } + void Accept(ASTVisitor& visitor) override { visitor.VisitArrayExpression(*this); } + + public: + std::vector elements; + }; + + class PrefixIncrementExpression : public Expression + { + public: + PrefixIncrementExpression() { kind = NodeKind::kPrefixIncrementExpression; } + void Accept(ASTVisitor& visitor) override { visitor.VisitPrefixIncrementExpression(*this); } + + public: + ExpressionPtr argument; + }; + + class PrefixDecrementExpression : public Expression + { + public: + PrefixDecrementExpression() { kind = NodeKind::kPrefixDecrementExpression; } + void Accept(ASTVisitor& visitor) override { visitor.VisitPrefixDecrementExpression(*this); } + + public: + ExpressionPtr argument; + }; + + class PostfixIncrementExpression : public Expression + { + public: + PostfixIncrementExpression() { kind = NodeKind::kPostfixIncrementExpression; } + void Accept(ASTVisitor& visitor) override { visitor.VisitPostfixIncrementExpression(*this); } + + public: + ExpressionPtr argument; + }; + + class PostfixDecrementExpression : public Expression + { + public: + PostfixDecrementExpression() { kind = NodeKind::kPostfixDecrementExpression; } + void Accept(ASTVisitor& visitor) override { visitor.VisitPostfixDecrementExpression(*this); } + + public: + ExpressionPtr argument; + }; + + class FunctionPointerExpression : public Expression + { + public: + FunctionPointerExpression() { kind = NodeKind::kFunctionPointerExpression; } + void Accept(ASTVisitor& visitor) override { visitor.VisitFunctionPointerExpression(*this); } + + public: + ExpressionPtr argument; + }; + + class UnpackPattern : public ASTNode + { + public: + UnpackPattern() { kind = NodeKind::kUnpackPattern; } + void Accept(ASTVisitor& visitor) override { visitor.VisitUnpackPattern(*this); } + + public: + std::vector names; + }; + + class VarDeclaration : public ASTNode + { + public: + VarDeclaration() { kind = NodeKind::kVarDeclaration; } + void Accept(ASTVisitor& visitor) override { visitor.VisitVarDeclaration(*this); } + + public: + std::string name; + std::optional type_name; + ExpressionPtr initial_value; + }; + + class StaticDeclaration : public ASTNode + { + public: + StaticDeclaration() { kind = NodeKind::kStaticDeclaration; } + void Accept(ASTVisitor& visitor) override { visitor.VisitStaticDeclaration(*this); } + + public: + std::string name; + std::optional type_name; + ExpressionPtr initial_value; + ReferenceModifier reference_modifier = ReferenceModifier::kNone; + }; + + class GlobalDeclaration : public ASTNode + { + public: + GlobalDeclaration() { kind = NodeKind::kGlobalDeclaration; } + void Accept(ASTVisitor& visitor) override { visitor.VisitGlobalDeclaration(*this); } + + public: + std::string name; + std::optional type_name; + ExpressionPtr initial_value; + }; + + class FieldDeclaration : public ASTNode + { + public: + FieldDeclaration() { kind = NodeKind::kFieldDeclaration; } + void Accept(ASTVisitor& visitor) override { visitor.VisitFieldDeclaration(*this); } + + public: + std::string name; + std::optional type_name; + ExpressionPtr initial_value; + ReferenceModifier reference_modifier = ReferenceModifier::kNone; + }; + + using LeftHandSide = std::variant< + std::unique_ptr, + std::unique_ptr, + std::unique_ptr, + std::unique_ptr, + std::unique_ptr, + std::unique_ptr, + std::unique_ptr, + std::unique_ptr>; + + class AssignmentExpression : public Expression + { + public: + AssignmentExpression() { kind = NodeKind::kAssignmentExpression; } + void Accept(ASTVisitor& visitor) override { visitor.VisitAssignmentExpression(*this); } + + public: + LeftHandSide left; + AssignmentOperator op; + ExpressionPtr right; + }; + + class TSSQLExpression : public Expression + { + public: + TSSQLExpression() { kind = NodeKind::kTSSQLSelectExpression; } + void Accept(ASTVisitor& visitor) override { visitor.VisitTSSQLExpression(*this); } + + public: + TSSQLExpressionType sql_type; + std::string raw_sql; + }; + + class Statement : public ASTNode + { + public: + virtual ~Statement() = default; + }; + + class ExpressionStatement : public Statement + { + public: + ExpressionStatement() { kind = NodeKind::kExpressionStatement; } + + public: + void Accept(ASTVisitor& visitor) override { visitor.VisitExpressionStatement(*this); } + ExpressionPtr expression; + }; + + class AssignmentStatement : public Statement + { + public: + AssignmentStatement() { kind = NodeKind::kAssignmentStatement; } + void Accept(ASTVisitor& visitor) override { visitor.VisitAssignmentStatement(*this); } + + public: + LeftHandSide left; + AssignmentOperator op; + ExpressionPtr right; + }; + + class BlockStatement : public Statement + { + public: + BlockStatement() { kind = NodeKind::kBlockStatement; } + void Accept(ASTVisitor& visitor) override { visitor.VisitBlockStatement(*this); } + + public: + std::vector statements; + }; + + class VarStatement : public Statement + { + public: + VarStatement() { kind = NodeKind::kVarStatement; } + void Accept(ASTVisitor& visitor) override { visitor.VisitVarStatement(*this); } + + public: + std::vector> declarations; + }; + + class StaticStatement : public Statement + { + public: + StaticStatement() { kind = NodeKind::kStaticStatement; } + void Accept(ASTVisitor& visitor) override { visitor.VisitStaticStatement(*this); } + + public: + std::vector> declarations; + }; + + class GlobalStatement : public Statement + { + public: + GlobalStatement() { kind = NodeKind::kGlobalStatement; } + void Accept(ASTVisitor& visitor) override { visitor.VisitGlobalStatement(*this); } + + public: + std::vector> declarations; + }; + + class ConstStatement : public Statement + { + public: + ConstStatement() { kind = NodeKind::kConstStatement; } + void Accept(ASTVisitor& visitor) override { visitor.VisitConstStatement(*this); } + + public: + std::string name; + std::optional type_name; + ExpressionPtr value; + }; + + class IfStatement : public Statement + { + public: + struct Branch + { + ExpressionPtr condition; + StatementPtr body; + }; + + IfStatement() { kind = NodeKind::kIfStatement; } + void Accept(ASTVisitor& visitor) override { visitor.VisitIfStatement(*this); } + + public: + std::vector branches; + }; + + class ForInStatement : public Statement + { + public: + ForInStatement() { kind = NodeKind::kForInStatement; } + void Accept(ASTVisitor& visitor) override { visitor.VisitForInStatement(*this); } + + public: + std::string key; + std::string value; + ExpressionPtr collection; + StatementPtr body; + }; + + class ForToStatement : public Statement + { + public: + ForToStatement() { kind = NodeKind::kForToStatement; } + void Accept(ASTVisitor& visitor) override { visitor.VisitForToStatement(*this); } + + public: + std::string counter; + ExpressionPtr start; + ExpressionPtr end; + bool is_downto; + StatementPtr body; + }; + + class WhileStatement : public Statement + { + public: + WhileStatement() { kind = NodeKind::kWhileStatement; } + void Accept(ASTVisitor& visitor) override { visitor.VisitWhileStatement(*this); } + + public: + ExpressionPtr condition; + StatementPtr body; + }; + + class RepeatStatement : public Statement + { + public: + RepeatStatement() { kind = NodeKind::kRepeatStatement; } + void Accept(ASTVisitor& visitor) override { visitor.VisitRepeatStatement(*this); } + + public: + std::vector body; + ExpressionPtr condition; + }; + + class CaseStatement : public Statement + { + public: + struct Branch + { + std::vector values; + StatementPtr body; + }; + + CaseStatement() { kind = NodeKind::kCaseStatement; } + void Accept(ASTVisitor& visitor) override { visitor.VisitCaseStatement(*this); } + + public: + ExpressionPtr discriminant; + std::vector branches; + StatementPtr default_case; + }; + + class TryStatement : public Statement + { + public: + TryStatement() { kind = NodeKind::kTryStatement; } + void Accept(ASTVisitor& visitor) override { visitor.VisitTryStatement(*this); } + + public: + StatementPtr try_body; + StatementPtr except_body; + }; + + class BreakStatement : public Statement + { + public: + BreakStatement() { kind = NodeKind::kBreakStatement; } + void Accept(ASTVisitor& visitor) override { visitor.VisitBreakStatement(*this); } + }; + + class ContinueStatement : public Statement + { + public: + ContinueStatement() { kind = NodeKind::kContinueStatement; } + void Accept(ASTVisitor& visitor) override { visitor.VisitContinueStatement(*this); } + }; + + class ReturnStatement : public Statement + { + public: + ReturnStatement() { kind = NodeKind::kReturnStatement; } + void Accept(ASTVisitor& visitor) override { visitor.VisitReturnStatement(*this); } + + public: + ExpressionPtr value; + }; + + class UsesStatement: public Statement + { + public: + UsesStatement() { kind = NodeKind::kUsesStatement; } + void Accept(ASTVisitor& visitor) override { visitor.VisitUsesStatement(*this); } + + public: + std::vector modules; }; struct Parameter { - Location location; - Location name_location; std::string name; std::optional type_name; - std::optional default_value; + ExpressionPtr default_value; bool is_var = false; bool is_out = false; + Location location; }; struct Signature @@ -51,284 +890,280 @@ namespace lsp::language::ast std::optional return_type; }; - // ==================== 前向声明 ==================== - - struct VarDeclaration; - struct StaticDeclaration; - struct GlobalDeclaration; - struct ConstDeclaration; - struct AssignmentStatement; - struct FunctionDefinition; - struct ClassDefinition; - struct Method; - struct ExternalMethod; - struct ConstructorDeclaration; - struct DestructorDeclaration; - struct Property; - struct UsesClause; - struct Block; - struct UnitDefinition; - - using ASTNode = std::variant< - std::monostate, - FunctionDefinition, - ClassDefinition, - VarDeclaration, - StaticDeclaration, - GlobalDeclaration, - ConstDeclaration, - AssignmentStatement, - Method, - ExternalMethod, - Property, - UsesClause, - UnitDefinition, - Expression, - Block>; - - // ==================== AST 节点定义 ==================== - - struct Block - { - Location location; - std::string node_type; - std::vector statements; - }; - - struct VarDeclaration - { - Location location; - Location name_location; - std::string node_type; - std::string name; - std::optional type_name; - std::optional value; - }; - - struct StaticDeclaration - { - Location location; - Location name_location; - std::string node_type; - std::string name; - std::optional type_name; - std::optional value; - }; - - struct GlobalDeclaration - { - Location location; - Location name_location; - std::string node_type; - std::string name; - std::optional type_name; - std::optional value; - }; - - struct ConstDeclaration - { - Location location; - Location name_location; - std::string node_type; - std::string name; - std::optional type_name; - Expression value; - }; - - struct AssignmentStatement - { - Location location; - Location name_location; - std::string node_type; - std::string name; - Expression value; - }; - - struct FunctionDefinition - { - Location location; - Location name_location; - std::string node_type; - std::string name; - bool is_overload = false; - Signature signature; - Block body; - }; - - enum class Access - { - kPublic, - kProtected, - kPrivate - }; - - struct Property - { - Location location; - Location name_location; - std::string node_type; - std::string name; - std::optional type_name; - std::optional getter; - std::optional setter; - }; - - enum class Modifier - { - kNone, - kVirtual, - kOverride, - kOverload - }; - - struct Method - { - Location location; - Location name_location; - std::string node_type; - std::string name; - Signature signature; - bool is_class_method = false; - Modifier modifier = Modifier::kNone; - std::optional body; - }; - - struct ExternalMethod - { - Location location; - Location name_location; - std::string node_type; - std::string class_name; - std::string method_name; - Signature signature; - bool is_class_method = false; - bool is_operator = false; - std::string operator_symbol; - Modifier modifier = Modifier::kNone; - Block body; - }; - - struct ConstructorDeclaration - { - Location location; - Location name_location; - std::string node_type; - Signature signature; - std::optional body; - }; - - struct DestructorDeclaration - { - Location location; - Location name_location; - std::string node_type; - std::optional body; - }; - - struct ClassMember - { - Access access = Access::kPublic; - std::variant< - std::monostate, - VarDeclaration, - StaticDeclaration, - Method, - ConstructorDeclaration, - DestructorDeclaration, - Property> - content; - }; - - struct ClassDefinition - { - Location location; - Location name_location; - std::string node_type; - std::string name; - std::vector parents; - std::vector members; - }; - - struct UsesClause - { - Location location; - std::string node_type; - std::vector units; - }; - - struct UnitDefinition - { - Location location; - Location name_location; - std::string node_type; - std::string name; - std::optional uses; - std::vector interface_statements; - std::vector implementation_statements; - std::vector initialization_statements; - std::vector finalization_statements; - }; - - // ==================== 错误处理 ==================== - - enum class ErrorSeverity - { - Warning, - Error, - Fatal - }; - - struct ParseError - { - Location location; - std::string node_type; - std::string message; - ErrorSeverity severity = ErrorSeverity::Error; - }; - - struct ParseResult - { - std::vector nodes; - std::vector errors; - - inline bool HasErrors() const { return !errors.empty(); } - inline bool IsSuccess() const { return errors.empty(); } - }; - - // ==================== Result 模板 ==================== - - template - class Result + class FunctionDefinition : public Statement { public: - static Result Ok(T&& val) - { - return { true, std::move(val), "", ErrorSeverity::Error }; - } + FunctionDefinition() { kind = NodeKind::kFunctionDefinition; } + void Accept(ASTVisitor& visitor) override { visitor.VisitFunctionDefinition(*this); } - static Result Err(const std::string& msg, ErrorSeverity sev = ErrorSeverity::Error) - { - return { false, std::nullopt, msg, sev }; - } - - inline bool IsOk() const { return success; } - inline bool IsErr() const { return !success; } - - T Unwrap() && - { - if (!success) - throw std::runtime_error("Unwrap on error: " + error); - return std::move(value).value(); - } - - T UnwrapOr(T&& default_val) && - { - return success ? std::move(*value) : std::move(default_val); - } - - bool success = false; - std::optional value; - std::string error; - ErrorSeverity severity = ErrorSeverity::Error; + public: + std::string name; + Signature signature; + StatementPtr body; + bool is_overload; }; + + class FunctionDeclaration : public Statement + { + public: + FunctionDeclaration() { kind = NodeKind::kFunctionDeclaration; } + void Accept(ASTVisitor& visitor) override { visitor.VisitFunctionDeclaration(*this); } + + public: + std::string name; + Signature signature; + bool is_overload; + }; + + class AnonymousFunctionExpression : public Expression + { + public: + AnonymousFunctionExpression() { kind = NodeKind::kAnonymousFunctionExpression; } + void Accept(ASTVisitor& visitor) override { visitor.VisitAnonymousFunctionExpression(*this); } + + public: + Signature signature; + StatementPtr body; + }; + + class MethodDeclaration : public Statement + { + public: + MethodDeclaration() { kind = NodeKind::kMethodDeclaration; } + void Accept(ASTVisitor& visitor) override { visitor.VisitMethodDeclaration(*this); } + + public: + std::string name; + Signature signature; + StatementPtr body; + MethodModifier modifier = MethodModifier::kNone; + MethodType method_type = MethodType::kNormal; + bool is_class_method = false; + bool is_operator_overload = false; + std::string operator_symbol; + }; + + class PropertyDeclaration : public Statement + { + public: + PropertyDeclaration() { kind = NodeKind::kPropertyDeclaration; } + void Accept(ASTVisitor& visitor) override { visitor.VisitPropertyDeclaration(*this); } + + public: + std::string name; + std::optional type_name; + std::optional index_value; + std::optional read_accessor; + std::optional write_accessor; + }; + + class ClassMember : public ASTNode + { + public: + ClassMember() { kind = NodeKind::kClassMember; } + void Accept(ASTVisitor& visitor) override { visitor.VisitClassMember(*this); } + + public: + AccessModifier access_modifier = AccessModifier::kPublic; + std::variant< + std::unique_ptr, + std::unique_ptr, + std::unique_ptr, + std::unique_ptr> + member; + }; + + class ClassDefinition : public Statement + { + public: + ClassDefinition() { kind = NodeKind::kClassDefinition; } + void Accept(ASTVisitor& visitor) override { visitor.VisitClassDefinition(*this); } + + public: + std::string name; + std::vector parent_classes; + std::vector> members; + }; + + class UnitDefinition : public Statement + { + public: + UnitDefinition() { kind = NodeKind::kUnitDefinition; } + void Accept(ASTVisitor& visitor) override { visitor.VisitUnitDefinition(*this); } + + public: + std::string name; + std::vector interface_statements; + std::vector implementation_statements; + std::vector initialization_statements; + std::vector finalization_statements; + }; + + class ExternalMethodDefinition : public Statement + { + public: + ExternalMethodDefinition() { kind = NodeKind::kExternalMethodDefinition; } + void Accept(ASTVisitor& visitor) override { visitor.VisitExternalMethodDefinition(*this); } + + public: + std::string owner_class; + std::string name; + Signature signature; + StatementPtr body; + MethodModifier modifier = MethodModifier::kNone; + MethodType method_type = MethodType::kNormal; + bool is_operator_overload = false; + bool is_class_method = false; + std::string operator_symbol; + }; + + template + std::unique_ptr MakeNode(Args&&... args) + { + return std::make_unique(std::forward(args)...); + } + + template + T* CastNode(ASTNode* node) + { + return dynamic_cast(node); + } + + template + const T* CastNode(const ASTNode* node) + { + return dynamic_cast(node); + } + + inline std::string GetBinaryOperatorSymbol(BinaryOperator op) + { + switch (op) + { + // Arithmetic + case BinaryOperator::kAdd: + return "+"; + case BinaryOperator::kSubtract: + return "-"; + case BinaryOperator::kMultiply: + return "*"; + case BinaryOperator::kDivide: + return "/"; + case BinaryOperator::kIntDivide: + return "\\"; + case BinaryOperator::kModulo: + return "%"; + case BinaryOperator::kPower: + return "^"; + case BinaryOperator::kLogarithm: + return "~"; + + // Comparison + case BinaryOperator::kEqual: + return "="; + case BinaryOperator::kNotEqual: + return "<>"; + case BinaryOperator::kGreater: + return ">"; + case BinaryOperator::kGreaterEqual: + return ">="; + case BinaryOperator::kLess: + return "<"; + case BinaryOperator::kLessEqual: + return "<="; + case BinaryOperator::kDotEqual: + return ".="; + case BinaryOperator::kDotNotEqual: + return ".<>"; + case BinaryOperator::kDotGreater: + return ".>"; + case BinaryOperator::kDotGreaterEqual: + return ".>="; + case BinaryOperator::kDotLess: + return ".<"; + case BinaryOperator::kDotLessEqual: + return ".<="; + case BinaryOperator::kLike: + return "like"; + case BinaryOperator::kIs: + return "is"; + case BinaryOperator::kIn: + return "in"; + + // Logical + case BinaryOperator::kLogicalOr: + return "or"; + case BinaryOperator::kLogicalAnd: + return "and"; + case BinaryOperator::kDotLogicalOr: + return ".||"; + case BinaryOperator::kDotLogicalAnd: + return ".&&"; + + // Bitwise + case BinaryOperator::kBitwiseOr: + return ".|"; + case BinaryOperator::kBitwiseAnd: + return ".&"; + case BinaryOperator::kBitwiseXor: + return ".^"; + case BinaryOperator::kShl: + return "shl"; + case BinaryOperator::kShr: + return "shr"; + case BinaryOperator::kRol: + return "rol"; + case BinaryOperator::kRor: + return "ror"; + + // Matrix + case BinaryOperator::kMatrixMultiply: + return ":*"; + case BinaryOperator::kMatrixDivide: + return ":/"; + case BinaryOperator::kMatrixIntDivide: + return ":\\"; + case BinaryOperator::kMatrixPower: + return ":^"; + case BinaryOperator::kMatrixConcat: + return ":|"; + case BinaryOperator::kMatrixConcatVertical: + return "|"; + + // Set + case BinaryOperator::kUnion: + return "union"; + case BinaryOperator::kUnion2: + return "union2"; + case BinaryOperator::kIntersect: + return "intersect"; + case BinaryOperator::kOutersect: + return "outersect"; + case BinaryOperator::kMinus: + return "minus"; + + // Other + case BinaryOperator::kConcatenation: + return "$"; + case BinaryOperator::kRange: + return "->"; + + default: + return "unknown"; + } + } + + inline std::string GetAssignmentOperatorSymbol(AssignmentOperator op) + { + switch (op) + { + case AssignmentOperator::kAssign: + return ":="; + case AssignmentOperator::kAddAssign: + return "+="; + case AssignmentOperator::kSubtractAssign: + return "-="; + default: + return "unknown"; + } + } }