🐛 fix(ast): support single-variable for-in fallback
normalize single-variable for-in nodes in the deserializer and rewrite legacy input in test_ast when the bundled parser cannot generate updated parse tables. skip known-invalid tsf fixtures in test.sh so batch runs can continue past syntax errors that the grammar should not accept.
This commit is contained in:
@@ -524,6 +524,8 @@ namespace lsp::language::ast::detail
|
||||
|
||||
TSNode default_value_node = ts_node_child_by_field_name(param_node, "default_value", 13);
|
||||
param->default_value = ParseExpression(default_value_node, ctx);
|
||||
|
||||
parameters.push_back(std::move(param));
|
||||
}
|
||||
|
||||
return parameters;
|
||||
@@ -896,6 +898,7 @@ namespace lsp::language::ast::detail
|
||||
|
||||
std::string op_text = ts_utils::Text(op_node, ctx.Source());
|
||||
expr->op = StringToBinaryOperator(op_text);
|
||||
expr->operator_location = ts_utils::NodeLocation(op_node);
|
||||
|
||||
return expr;
|
||||
}
|
||||
@@ -1645,11 +1648,11 @@ namespace lsp::language::ast::detail
|
||||
}
|
||||
|
||||
// 检查是否是类方法
|
||||
uint32_t count = ts_node_child_count(node);
|
||||
uint32_t count = ts_node_child_count(child);
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
TSNode child = ts_node_child(node, i);
|
||||
std::string_view child_type = ts_node_type(child);
|
||||
TSNode method_child = ts_node_child(child, i);
|
||||
std::string_view child_type = ts_node_type(method_child);
|
||||
if (child_type == "class")
|
||||
{
|
||||
ext_method->is_static = true;
|
||||
@@ -1735,8 +1738,6 @@ namespace lsp::language::ast::detail
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
TSNode child = ts_node_child(node, i);
|
||||
if (!ts_node_is_named(child))
|
||||
continue;
|
||||
std::string text = ts_utils::Text(child, ctx.Source());
|
||||
if (lsp::utils::ToLower(text) == "overload")
|
||||
{
|
||||
@@ -1784,8 +1785,6 @@ namespace lsp::language::ast::detail
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
TSNode child = ts_node_child(node, i);
|
||||
if (!ts_node_is_named(child))
|
||||
continue;
|
||||
std::string text = ts_utils::Text(child, ctx.Source());
|
||||
if (lsp::utils::ToLower(text) == "overload")
|
||||
{
|
||||
@@ -1882,8 +1881,6 @@ namespace lsp::language::ast::detail
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
TSNode child = ts_node_child(node, i);
|
||||
if (!ts_node_is_named(child))
|
||||
continue;
|
||||
|
||||
std::string text = lsp::utils::ToLower(ts_utils::Text(child, ctx.Source()));
|
||||
if (text == "define")
|
||||
@@ -2035,6 +2032,21 @@ namespace lsp::language::ast::detail
|
||||
stmt->value = ts_utils::Text(value_node, ctx.Source());
|
||||
stmt->value_location = ts_utils::NodeLocation(value_node);
|
||||
}
|
||||
else if (!stmt->key.empty())
|
||||
{
|
||||
// Grammar allows `for value in collection do ...`; normalize it into value slot.
|
||||
stmt->value = stmt->key;
|
||||
stmt->value_location = stmt->key_location;
|
||||
stmt->key.clear();
|
||||
stmt->key_location = {};
|
||||
}
|
||||
|
||||
if (!stmt->key.empty() && !stmt->value.empty() && stmt->key == stmt->value)
|
||||
{
|
||||
// Backward-compatible normalization for pre-rewrite parser fallback.
|
||||
stmt->key.clear();
|
||||
stmt->key_location = {};
|
||||
}
|
||||
|
||||
TSNode collection_node = ts_node_child_by_field_name(node, "collection", 10);
|
||||
stmt->collection = ParseExpression(collection_node, ctx);
|
||||
@@ -2801,9 +2813,9 @@ namespace lsp::language::ast::detail
|
||||
};
|
||||
}
|
||||
|
||||
TSNode value_node = ts_node_child_by_field_name(node, "value", 5);
|
||||
if (!ts_node_is_null(value_node))
|
||||
declarations.back()->initializer = ParseExpression(value_node, ctx);
|
||||
TSNode initializer_node = ts_node_child_by_field_name(node, "initializer", 11);
|
||||
if (!ts_node_is_null(initializer_node))
|
||||
declarations.back()->initializer = ParseExpression(initializer_node, ctx);
|
||||
}
|
||||
|
||||
// 如果只有一个声明,直接返回
|
||||
|
||||
Reference in New Issue
Block a user