#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->span = loc; 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, std::string_view 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 = TypeAnnotation{ .name = ts::Text(type_name_node, ctx.Source()), .location = ts::NodeLocation(type_name_node) }; } 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; } 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 = 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()) { TSNode type_node = ts_node_child_by_field_name(param_node, "type_name", 9); if (!ts_node_is_null(type_node)) all_params.back().type = TypeAnnotation{ .name = ts::Text(type_node, ctx.Source()), .location = ts::NodeLocation(type_node) }; TSNode default_node = ts_node_child_by_field_name(param_node, "default", 7); if (!ts_node_is_null(default_node)) all_params.back().default_value = ParseExpression(default_node, ctx); } } 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->span = loc; 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) { auto call = MakeNode(); call->kind = NodeKind::kCallExpression; call->span = ts::NodeLocation(node); TSNode echo_node = ts_node_child(node, 0); auto echo_id = MakeNode(); echo_id->kind = NodeKind::kIdentifier; echo_id->span = ts::NodeLocation(echo_node); echo_id->name = "echo"; echo_id->location = ts::NodeLocation(echo_node); 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) { auto call = MakeNode(); call->kind = NodeKind::kCallExpression; call->span = ts::NodeLocation(node); TSNode raise_node = ts_node_child(node, 0); auto raise_id = MakeNode(); raise_id->kind = NodeKind::kIdentifier; raise_id->span = ts::NodeLocation(raise_node); raise_id->name = "raise"; raise_id->location = ts::NodeLocation(raise_node); 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) { auto call = MakeNode(); call->kind = NodeKind::kCallExpression; call->span = ts::NodeLocation(node); TSNode new_node = ts_node_child(node, 0); auto new_id = MakeNode(); new_id->kind = NodeKind::kIdentifier; new_id->span = ts::NodeLocation(new_node); new_id->name = "new"; new_id->location = ts::NodeLocation(new_node); 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) { auto call = MakeNode(); call->kind = NodeKind::kCallExpression; call->span = ts::NodeLocation(node); TSNode inherited_node = ts_node_child(node, 0); auto inherited_id = MakeNode(); inherited_id->kind = NodeKind::kIdentifier; inherited_id->span = ts::NodeLocation(inherited_node); inherited_id->name = "inherited"; inherited_id->location = ts::NodeLocation(inherited_node); call->callee = std::move(inherited_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->span = loc; id->name = std::move(name); return id; } // 字面量 if (node_type == "number") { auto lit = MakeNode(); lit->kind = NodeKind::kLiteral; lit->span = loc; lit->literal_kind = LiteralKind::kNumber; lit->name = ts::Text(node, ctx.Source()); lit->location = loc; return lit; } if (node_type == "string") { auto lit = MakeNode(); lit->kind = NodeKind::kLiteral; lit->span = loc; lit->literal_kind = LiteralKind::kString; lit->name = ts::Text(node, ctx.Source()); lit->location = loc; return lit; } if (node_type == "boolean") { auto lit = MakeNode(); lit->kind = NodeKind::kLiteral; lit->span = loc; lit->literal_kind = LiteralKind::kBoolean; lit->name = ts::Text(node, ctx.Source()); lit->location = loc; return lit; } if (node_type == "nil") { auto lit = MakeNode(); lit->kind = NodeKind::kLiteral; lit->span = loc; lit->literal_kind = LiteralKind::kNil; lit->name = "nil"; lit->location = loc; return lit; } if (node_type == "infinity") { auto lit = MakeNode(); lit->kind = NodeKind::kLiteral; lit->span = loc; lit->literal_kind = LiteralKind::kInfinity; lit->name = ts::Text(node, ctx.Source()); lit->location = loc; return lit; } if (node_type == "ellipsis") { auto lit = MakeNode(); lit->kind = NodeKind::kLiteral; lit->span = loc; lit->literal_kind = LiteralKind::kEllipsis; lit->name = "..."; lit->location = loc; return lit; } // 默认:创建一个标识符表达式 std::string text = ts::Text(node, ctx.Source()); if (!text.empty()) { auto id = MakeNode(); id->kind = NodeKind::kIdentifier; id->span = loc; 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->span = loc; 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->span = loc; 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->span = loc; 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->span = loc; 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->span = loc; 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->span = loc; 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->span = loc; 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->span = loc; expr->condition = std::move(condition); expr->consequence = std::move(consequence); expr->alternative = std::move(alternative); return expr; } ExpressionPtr ParseCallExpression(TSNode node, ParseContext& ctx) { auto expr = MakeNode(); expr->kind = NodeKind::kCallExpression; expr->span = ts::NodeLocation(node); TSNode callee_node = ts_node_child_by_field_name(node, "function", 8); if (!ts_node_is_null(callee_node)) { auto callee = ParseExpression(callee_node, ctx); 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()); arg.location = ts::NodeLocation(name_node); } 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)); } expr->callee = std::move(callee); expr->arguments = std::move(arguments); } return expr; } ExpressionPtr ParseAttributeExpression(TSNode node, ParseContext& ctx) { auto expr = MakeNode(); expr->kind = NodeKind::kAttributeExpression; expr->span = 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)) { auto object = ParseExpression(obj_node, ctx); expr->object = std::move(object); } if (!ts_node_is_null(attr_node)) { expr->name = ts::Text(attr_node, ctx.Source()); expr->location = ts::NodeLocation(attr_node); } 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->span = loc; 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->span = loc; 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->span = loc; 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->span = ts::NodeLocation(node); 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->span = loc; 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->span = ts::NodeLocation(node); 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->span = loc; 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->span = loc; 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->span = loc; stmt->expression = std::move(expr); return stmt; } ExpressionPtr ParseAssignmentExpression(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) || 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->span = loc; 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->span = loc; 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) { 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)) { 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->span = name_loc; decl->name = std::move(name); decl->type = std::nullopt; 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); TSNode type_node = ts_node_child_by_field_name(decl_node, "type_name", 9); if (!declarations.empty() && !ts_node_is_null(type_node)) declarations.back()->type = TypeAnnotation{ .name = ts::Text(type_node, ctx.Source()), .location = ts::NodeLocation(type_node) }; } auto stmt = MakeNode(); stmt->kind = stmt_kind; stmt->span = loc; stmt->declarations = std::move(declarations); return stmt; } StatementPtr ParseVarStatement(TSNode node, ParseContext& ctx) { return ParseDeclarationStatement( node, ctx, NodeKind::kVarDeclaration, NodeKind::kVarStatement); } StatementPtr ParseStaticStatement(TSNode node, ParseContext& ctx) { return ParseDeclarationStatement( node, ctx, NodeKind::kStaticDeclaration, NodeKind::kStaticStatement); } StatementPtr ParseGlobalStatement(TSNode node, ParseContext& ctx) { return ParseDeclarationStatement( node, ctx, NodeKind::kGlobalDeclaration, NodeKind::kGlobalStatement); } 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->span = loc; 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->span = loc; 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->span = loc; 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->span = loc; 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->span = loc; 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 || std::string_view(field) != "body") 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->span = loc; 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; 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) != "branches") 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->span = loc; 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->span = loc; 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->span = loc; return stmt; } StatementPtr ParseContinueStatement(TSNode node, [[maybe_unused]] ParseContext& ctx) { Location loc = ts::NodeLocation(node); auto stmt = MakeNode(); stmt->kind = NodeKind::kContinueStatement; stmt->span = loc; return stmt; } StatementPtr ParseReturnStatement(TSNode node, ParseContext& ctx) { Location loc = ts::NodeLocation(node); auto stmt = MakeNode(); stmt->kind = NodeKind::kReturnStatement; stmt->span = loc; 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, ParseContext& ctx) { Location loc = ts::NodeLocation(node); auto uses = MakeNode(); uses->kind = NodeKind::kUsesStatement; uses->span = loc; 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) != "units") continue; TSNode child = ts_node_child(node, i); uses->units.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->span = loc; stmt->expression = std::move(expr); return stmt; } StatementPtr ParseFunctionDeclaration(TSNode node, ParseContext& ctx) { auto stmt = MakeNode(); stmt->kind = NodeKind::kFunctionDeclaration; stmt->span = ts::NodeLocation(node); TSNode name_node = ts_node_child_by_field_name(node, "name", 4); if (!ts_node_is_null(name_node)) { stmt->name = ts::Text(name_node, ctx.Source()); stmt->location = ts::NodeLocation(name_node); } Signature sig = ParseSignature(node, ctx); stmt->signature = std::move(sig); return stmt; } StatementPtr ParseFunctionDefinition(TSNode node, ParseContext& ctx) { auto stmt = MakeNode(); stmt->kind = NodeKind::kFunctionDefinition; stmt->span = ts::NodeLocation(node); TSNode name_node = ts_node_child_by_field_name(node, "name", 4); if (!ts_node_is_null(name_node)) { std::string name = ts::Text(name_node, ctx.Source()); stmt->name = std::move(name); stmt->location = ts::NodeLocation(name_node); } 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"); stmt->signature = std::move(sig); stmt->body = std::move(body); stmt->is_overload = is_overload; return stmt; } StatementPtr ParseMatrixIterationStatement(TSNode node, ParseContext& ctx) { auto stmt = MakeNode(); stmt->kind = NodeKind::kWhileStatement; stmt->span = 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); 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->span = loc; return block; } StatementPtr ParseTSLXCloseTag(TSNode node, [[maybe_unused]] ParseContext& ctx) { Location loc = ts::NodeLocation(node); auto block = MakeNode(); block->kind = NodeKind::kBlockStatement; block->span = loc; 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->span = loc; for (auto& expr : expressions) { auto expr_stmt = MakeNode(); expr_stmt->kind = NodeKind::kExpressionStatement; expr_stmt->span = expr->span; 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->span = loc; 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->span = loc; 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->span = loc; 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->span = loc; return block; } StatementPtr ParseUnitDefinition(TSNode node, ParseContext& ctx) { auto unit = MakeNode(); unit->kind = NodeKind::kUnitDefinition; unit->span = ts::NodeLocation(node); TSNode name_node = ts_node_child_by_field_name(node, "name", 4); if (!ts_node_is_null(name_node)) { unit->name = ts::Text(name_node, ctx.Source()); unit->location = ts::NodeLocation(name_node); } 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->span = loc; 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->name = ts::Text(op_node, ctx.Source()); method->location = ts::NodeLocation(op_node); } } else { method->name = ts::Text(name_node, ctx.Source()); method->location = ts::NodeLocation(name_node); } } 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->span = loc; 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()); prop->location = ts::NodeLocation(name_node); } 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; 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->span = name_loc; member->access_modifier = current_access; if (is_static) { auto decl = MakeNode(); decl->kind = NodeKind::kStaticDeclaration; decl->span = name_loc; 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->span = name_loc; 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)); } 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); TSNode type_node = ts_node_child_by_field_name(member_var_node, "type_name", 9); 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) { if (!ts_node_is_null(type_node)) decl_ptr->type = TypeAnnotation{ .name = ts::Text(type_node, ctx.Source()), .location = ts::NodeLocation(type_node) }; 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->span = loc; 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->span = loc; 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) { auto class_def = MakeNode(); class_def->kind = NodeKind::kClassDefinition; class_def->span = ts::NodeLocation(node); 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()); class_def->location = ts::NodeLocation(name_node); } 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) != "parent") continue; TSNode parent_node = ts_node_child(node, i); std::string parent_name; std::string_view parent_type = ts_node_type(parent_node); ClassDefinition::ParentClass parent; if (parent_type == "attribute") { auto attr = ParseAttributeExpression(parent_node, ctx); auto attr_expr = dynamic_cast(attr.get()); if (!attr_expr->name.empty()) { parent.name = attr_expr->name; parent.location = attr_expr->location; } if (attr_expr->object) { auto identifier = dynamic_cast(attr_expr->object.get()); parent.qualifier = identifier->name; parent.qualifier_location = identifier->location; } } else { parent.name = ts::Text(parent_node, ctx.Source()); parent.location = ts::NodeLocation(parent_node); } class_def->parent_classes.push_back(std::move(parent)); } 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) { auto ext_method = MakeNode(); ext_method->kind = NodeKind::kExternalMethodDefinition; ext_method->span = ts::NodeLocation(node); TSNode class_node = ts_node_child_by_field_name(node, "class_name", 10); if (!ts_node_is_null(class_node)) { ext_method->owner_class.name = ts::Text(class_node, ctx.Source()); ext_method->owner_class.location = ts::NodeLocation(class_node); } 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->name = ts::Text(op_node, ctx.Source()); ext_method->location = ts::NodeLocation(op_node); } 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()); ext_method->location = ts::NodeLocation(method_node); } } 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; } }