tsl-devkit/lsp-server/src/language/ast/detail.cpp

2481 lines
88 KiB
C++

#include <mutex>
#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<ExpressionStatement>();
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<std::string, BinaryOperator, utils::IHasher, utils::IEqualTo> 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<std::string, UnaryOperator, utils::IHasher, utils::IEqualTo> 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<std::string, AssignmentOperator, utils::IHasher, utils::IEqualTo> 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<ParseError> CollectSyntaxErrors(TSNode node, std::string_view source)
{
std::vector<ParseError> 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<Parameter> ParseParameters(TSNode params_node, ParseContext& ctx)
{
std::vector<Parameter> 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<Expression>(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<TSSQLExpression>();
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<CallExpression>();
call->kind = NodeKind::kCallExpression;
call->span = ts::NodeLocation(node);
TSNode echo_node = ts_node_child(node, 0);
auto echo_id = MakeNode<Identifier>();
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<CallExpression>();
call->kind = NodeKind::kCallExpression;
call->span = ts::NodeLocation(node);
TSNode raise_node = ts_node_child(node, 0);
auto raise_id = MakeNode<Identifier>();
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<CallExpression>();
call->kind = NodeKind::kCallExpression;
call->span = ts::NodeLocation(node);
TSNode new_node = ts_node_child(node, 0);
auto new_id = MakeNode<Identifier>();
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<CallExpression>();
call->kind = NodeKind::kCallExpression;
call->span = ts::NodeLocation(node);
TSNode inherited_node = ts_node_child(node, 0);
auto inherited_id = MakeNode<Identifier>();
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<Identifier>();
id->kind = NodeKind::kIdentifier;
id->span = loc;
id->name = std::move(name);
return id;
}
// 字面量
if (node_type == "number")
{
auto lit = MakeNode<Literal>();
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<Literal>();
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<Literal>();
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<Literal>();
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<Literal>();
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<Literal>();
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<Identifier>();
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<Expression>(loc, "left operand");
if (ts_node_is_null(right_node))
return ctx.ReportNullNode<Expression>(loc, "right operand");
auto left = ParseExpression(left_node, ctx);
auto right = ParseExpression(right_node, ctx);
if (!left)
return ctx.ReportParseFailed<Expression>(loc, "binary_expression", "failed to parse left operand");
if (!right)
return ctx.ReportParseFailed<Expression>(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<BinaryExpression>();
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<PrefixIncrementExpression>();
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<PrefixDecrementExpression>();
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<PostfixIncrementExpression>();
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<PostfixDecrementExpression>();
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<FunctionPointerExpression>();
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<UnaryExpression>();
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<TernaryExpression>();
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<CallExpression>();
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<CallExpression::Argument> 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<AttributeExpression>();
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<SubscriptExpression::Index> 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<SubscriptExpression>();
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<ArrayExpression::Element> 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<ArrayExpression>();
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<AnonymousFunctionExpression>();
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<Identifier>();
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<Identifier>();
id->kind = NodeKind::kIdentifier;
id->span = loc;
id->name = std::move(name);
return id;
}
// 属性访问
if (node_type == "attribute")
{
return std::unique_ptr<AttributeExpression>(
static_cast<AttributeExpression*>(ParseAttributeExpression(node, ctx).release()));
}
// 下标访问
if (node_type == "subscript")
{
return std::unique_ptr<SubscriptExpression>(
static_cast<SubscriptExpression*>(ParseSubscriptExpression(node, ctx).release()));
}
// 解包模式
if (node_type == "unpack_pattern")
{
return ParseUnpackPattern(node, ctx);
}
auto id = MakeNode<Identifier>();
id->kind = NodeKind::kIdentifier;
id->span = ts::NodeLocation(node);
id->name = ts::Text(node, ctx.Source());
return id;
}
std::unique_ptr<UnpackPattern> ParseUnpackPattern(TSNode node, ParseContext& ctx)
{
Location loc = ts::NodeLocation(node);
std::vector<std::string> 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<UnpackPattern>();
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<StatementPtr> 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<BlockStatement>();
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<ExpressionStatement>();
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<AssignmentExpression>();
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<AssignmentStatement>();
stmt->kind = NodeKind::kAssignmentStatement;
stmt->span = loc;
stmt->left = std::move(left);
stmt->op = op;
stmt->right = std::move(right);
return stmt;
}
// ===== 通用声明解析模板 =====
template<typename DeclType, typename StmtType>
StatementPtr ParseDeclarationStatement(TSNode node, ParseContext& ctx, NodeKind decl_kind, NodeKind stmt_kind)
{
Location loc = ts::NodeLocation(node);
std::vector<std::unique_ptr<DeclType>> 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<DeclType>();
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<StmtType>();
stmt->kind = stmt_kind;
stmt->span = loc;
stmt->declarations = std::move(declarations);
return stmt;
}
StatementPtr ParseVarStatement(TSNode node, ParseContext& ctx)
{
return ParseDeclarationStatement<VarDeclaration, VarStatement>(
node, ctx, NodeKind::kVarDeclaration, NodeKind::kVarStatement);
}
StatementPtr ParseStaticStatement(TSNode node, ParseContext& ctx)
{
return ParseDeclarationStatement<StaticDeclaration, StaticStatement>(
node, ctx, NodeKind::kStaticDeclaration, NodeKind::kStaticStatement);
}
StatementPtr ParseGlobalStatement(TSNode node, ParseContext& ctx)
{
return ParseDeclarationStatement<GlobalDeclaration, GlobalStatement>(
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<std::string> 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<ConstStatement>();
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<IfStatement::Branch> 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<IfStatement>();
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<ForInStatement>();
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<ForToStatement>();
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<WhileStatement>();
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<StatementPtr> 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<RepeatStatement>();
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<CaseStatement::Branch> 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<CaseStatement>();
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<TryStatement>();
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<BreakStatement>();
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<ContinueStatement>();
stmt->kind = NodeKind::kContinueStatement;
stmt->span = loc;
return stmt;
}
StatementPtr ParseReturnStatement(TSNode node, ParseContext& ctx)
{
Location loc = ts::NodeLocation(node);
auto stmt = MakeNode<ReturnStatement>();
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<UsesStatement>();
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<ExpressionStatement>();
stmt->kind = NodeKind::kExpressionStatement;
stmt->span = loc;
stmt->expression = std::move(expr);
return stmt;
}
StatementPtr ParseFunctionDeclaration(TSNode node, ParseContext& ctx)
{
auto stmt = MakeNode<FunctionDeclaration>();
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<FunctionDefinition>();
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<WhileStatement>();
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<BlockStatement>();
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<BlockStatement>();
block->kind = NodeKind::kBlockStatement;
block->span = loc;
return block;
}
StatementPtr ParseTSLXOutputTag(TSNode node, ParseContext& ctx)
{
Location loc = ts::NodeLocation(node);
std::vector<ExpressionPtr> 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<BlockStatement>();
block->kind = NodeKind::kBlockStatement;
block->span = loc;
for (auto& expr : expressions)
{
auto expr_stmt = MakeNode<ExpressionStatement>();
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<StatementPtr> 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<BlockStatement>();
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<BlockStatement>();
block->kind = NodeKind::kBlockStatement;
block->span = loc;
return block;
}
StatementPtr ParseHTMLPairedTag(TSNode node, ParseContext& ctx)
{
Location loc = ts::NodeLocation(node);
std::vector<StatementPtr> 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<BlockStatement>();
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<BlockStatement>();
block->kind = NodeKind::kBlockStatement;
block->span = loc;
return block;
}
StatementPtr ParseUnitDefinition(TSNode node, ParseContext& ctx)
{
auto unit = MakeNode<UnitDefinition>();
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<MethodDeclaration> ParseMethodDeclaration(TSNode node, ParseContext& ctx)
{
Location loc = ts::NodeLocation(node);
auto method = MakeNode<MethodDeclaration>();
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<PropertyDeclaration> ParsePropertyDeclaration(TSNode node, ParseContext& ctx)
{
Location loc = ts::NodeLocation(node);
auto prop = MakeNode<PropertyDeclaration>();
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<ClassMemberParseResult> ParseClassMember(TSNode node, ParseContext& ctx, AccessModifier current_access, ReferenceModifier current_reference)
{
std::vector<ClassMemberParseResult> 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<ClassMember>();
member->kind = NodeKind::kClassMember;
member->span = name_loc;
member->access_modifier = current_access;
if (is_static)
{
auto decl = MakeNode<StaticDeclaration>();
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<FieldDeclaration>();
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<decltype(*decl_ptr)>;
if constexpr (std::is_same_v<T, StaticDeclaration> ||
std::is_same_v<T, FieldDeclaration>)
{
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<ClassMember>();
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<ClassMember>();
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<ClassDefinition>();
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<AttributeExpression*>(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<Identifier*>(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<ExternalMethodDefinition>();
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;
}
}