Merge pull request #86091 from dalexeev/gds-fix-pot-gen-skips-some-nodes

GDScript: Fix POT generator skips some nodes
This commit is contained in:
Yuri Sizov 2023-12-19 20:33:09 +01:00
commit fc082dd735
2 changed files with 74 additions and 53 deletions

View file

@ -80,7 +80,7 @@ bool GDScriptEditorTranslationParserPlugin::_is_constant_string(const GDScriptPa
void GDScriptEditorTranslationParserPlugin::_traverse_class(const GDScriptParser::ClassNode *p_class) { void GDScriptEditorTranslationParserPlugin::_traverse_class(const GDScriptParser::ClassNode *p_class) {
for (int i = 0; i < p_class->members.size(); i++) { for (int i = 0; i < p_class->members.size(); i++) {
const GDScriptParser::ClassNode::Member &m = p_class->members[i]; const GDScriptParser::ClassNode::Member &m = p_class->members[i];
// There are 7 types of Member, but only class, function and variable can contain translatable strings. // Other member types can't contain translatable strings.
switch (m.type) { switch (m.type) {
case GDScriptParser::ClassNode::Member::CLASS: case GDScriptParser::ClassNode::Member::CLASS:
_traverse_class(m.m_class); _traverse_class(m.m_class);
@ -89,7 +89,11 @@ void GDScriptEditorTranslationParserPlugin::_traverse_class(const GDScriptParser
_traverse_function(m.function); _traverse_function(m.function);
break; break;
case GDScriptParser::ClassNode::Member::VARIABLE: case GDScriptParser::ClassNode::Member::VARIABLE:
_read_variable(m.variable); _assess_expression(m.variable->initializer);
if (m.variable->property == GDScriptParser::VariableNode::PROP_INLINE) {
_traverse_function(m.variable->setter);
_traverse_function(m.variable->getter);
}
break; break;
default: default:
break; break;
@ -98,11 +102,14 @@ void GDScriptEditorTranslationParserPlugin::_traverse_class(const GDScriptParser
} }
void GDScriptEditorTranslationParserPlugin::_traverse_function(const GDScriptParser::FunctionNode *p_func) { void GDScriptEditorTranslationParserPlugin::_traverse_function(const GDScriptParser::FunctionNode *p_func) {
_traverse_block(p_func->body); if (!p_func) {
} return;
}
void GDScriptEditorTranslationParserPlugin::_read_variable(const GDScriptParser::VariableNode *p_var) { for (int i = 0; i < p_func->parameters.size(); i++) {
_assess_expression(p_var->initializer); _assess_expression(p_func->parameters[i]->initializer);
}
_traverse_block(p_func->body);
} }
void GDScriptEditorTranslationParserPlugin::_traverse_block(const GDScriptParser::SuiteNode *p_suite) { void GDScriptEditorTranslationParserPlugin::_traverse_block(const GDScriptParser::SuiteNode *p_suite) {
@ -114,53 +121,51 @@ void GDScriptEditorTranslationParserPlugin::_traverse_block(const GDScriptParser
for (int i = 0; i < statements.size(); i++) { for (int i = 0; i < statements.size(); i++) {
const GDScriptParser::Node *statement = statements[i]; const GDScriptParser::Node *statement = statements[i];
// Statements with Node type constant, break, continue, pass, breakpoint are skipped because they can't contain translatable strings. // BREAK, BREAKPOINT, CONSTANT, CONTINUE, and PASS are skipped because they can't contain translatable strings.
switch (statement->type) { switch (statement->type) {
case GDScriptParser::Node::VARIABLE: case GDScriptParser::Node::ASSERT: {
_assess_expression(static_cast<const GDScriptParser::VariableNode *>(statement)->initializer); const GDScriptParser::AssertNode *assert_node = static_cast<const GDScriptParser::AssertNode *>(statement);
break; _assess_expression(assert_node->condition);
case GDScriptParser::Node::IF: { _assess_expression(assert_node->message);
const GDScriptParser::IfNode *if_node = static_cast<const GDScriptParser::IfNode *>(statement); } break;
_assess_expression(if_node->condition); case GDScriptParser::Node::ASSIGNMENT: {
//FIXME : if the elif logic is changed in GDScriptParser, then this probably will have to change as well. See GDScriptParser::TreePrinter::print_if(). _assess_assignment(static_cast<const GDScriptParser::AssignmentNode *>(statement));
_traverse_block(if_node->true_block); } break;
_traverse_block(if_node->false_block);
break;
}
case GDScriptParser::Node::FOR: { case GDScriptParser::Node::FOR: {
const GDScriptParser::ForNode *for_node = static_cast<const GDScriptParser::ForNode *>(statement); const GDScriptParser::ForNode *for_node = static_cast<const GDScriptParser::ForNode *>(statement);
_assess_expression(for_node->list); _assess_expression(for_node->list);
_traverse_block(for_node->loop); _traverse_block(for_node->loop);
break; } break;
} case GDScriptParser::Node::IF: {
case GDScriptParser::Node::WHILE: { const GDScriptParser::IfNode *if_node = static_cast<const GDScriptParser::IfNode *>(statement);
const GDScriptParser::WhileNode *while_node = static_cast<const GDScriptParser::WhileNode *>(statement); _assess_expression(if_node->condition);
_assess_expression(while_node->condition); _traverse_block(if_node->true_block);
_traverse_block(while_node->loop); _traverse_block(if_node->false_block);
break; } break;
}
case GDScriptParser::Node::MATCH: { case GDScriptParser::Node::MATCH: {
const GDScriptParser::MatchNode *match_node = static_cast<const GDScriptParser::MatchNode *>(statement); const GDScriptParser::MatchNode *match_node = static_cast<const GDScriptParser::MatchNode *>(statement);
_assess_expression(match_node->test); _assess_expression(match_node->test);
for (int j = 0; j < match_node->branches.size(); j++) { for (int j = 0; j < match_node->branches.size(); j++) {
_traverse_block(match_node->branches[j]->guard_body);
_traverse_block(match_node->branches[j]->block); _traverse_block(match_node->branches[j]->block);
} }
break; } break;
} case GDScriptParser::Node::RETURN: {
case GDScriptParser::Node::RETURN:
_assess_expression(static_cast<const GDScriptParser::ReturnNode *>(statement)->return_value); _assess_expression(static_cast<const GDScriptParser::ReturnNode *>(statement)->return_value);
break; } break;
case GDScriptParser::Node::ASSERT: case GDScriptParser::Node::VARIABLE: {
_assess_expression((static_cast<const GDScriptParser::AssertNode *>(statement))->condition); _assess_expression(static_cast<const GDScriptParser::VariableNode *>(statement)->initializer);
break; } break;
case GDScriptParser::Node::ASSIGNMENT: case GDScriptParser::Node::WHILE: {
_assess_assignment(static_cast<const GDScriptParser::AssignmentNode *>(statement)); const GDScriptParser::WhileNode *while_node = static_cast<const GDScriptParser::WhileNode *>(statement);
break; _assess_expression(while_node->condition);
default: _traverse_block(while_node->loop);
} break;
default: {
if (statement->is_expression()) { if (statement->is_expression()) {
_assess_expression(static_cast<const GDScriptParser::ExpressionNode *>(statement)); _assess_expression(static_cast<const GDScriptParser::ExpressionNode *>(statement));
} }
break; } break;
} }
} }
} }
@ -172,25 +177,25 @@ void GDScriptEditorTranslationParserPlugin::_assess_expression(const GDScriptPar
return; return;
} }
// ExpressionNode of type await, cast, get_node, identifier, literal, preload, self, subscript, unary are ignored as they can't be CallNode // GET_NODE, IDENTIFIER, LITERAL, PRELOAD, SELF, and TYPE are skipped because they can't contain translatable strings.
// containing translation strings.
switch (p_expression->type) { switch (p_expression->type) {
case GDScriptParser::Node::ARRAY: { case GDScriptParser::Node::ARRAY: {
const GDScriptParser::ArrayNode *array_node = static_cast<const GDScriptParser::ArrayNode *>(p_expression); const GDScriptParser::ArrayNode *array_node = static_cast<const GDScriptParser::ArrayNode *>(p_expression);
for (int i = 0; i < array_node->elements.size(); i++) { for (int i = 0; i < array_node->elements.size(); i++) {
_assess_expression(array_node->elements[i]); _assess_expression(array_node->elements[i]);
} }
break; } break;
} case GDScriptParser::Node::ASSIGNMENT: {
case GDScriptParser::Node::ASSIGNMENT:
_assess_assignment(static_cast<const GDScriptParser::AssignmentNode *>(p_expression)); _assess_assignment(static_cast<const GDScriptParser::AssignmentNode *>(p_expression));
break; } break;
case GDScriptParser::Node::AWAIT: {
_assess_expression(static_cast<const GDScriptParser::AwaitNode *>(p_expression)->to_await);
} break;
case GDScriptParser::Node::BINARY_OPERATOR: { case GDScriptParser::Node::BINARY_OPERATOR: {
const GDScriptParser::BinaryOpNode *binary_op_node = static_cast<const GDScriptParser::BinaryOpNode *>(p_expression); const GDScriptParser::BinaryOpNode *binary_op_node = static_cast<const GDScriptParser::BinaryOpNode *>(p_expression);
_assess_expression(binary_op_node->left_operand); _assess_expression(binary_op_node->left_operand);
_assess_expression(binary_op_node->right_operand); _assess_expression(binary_op_node->right_operand);
break; } break;
}
case GDScriptParser::Node::CALL: { case GDScriptParser::Node::CALL: {
const GDScriptParser::CallNode *call_node = static_cast<const GDScriptParser::CallNode *>(p_expression); const GDScriptParser::CallNode *call_node = static_cast<const GDScriptParser::CallNode *>(p_expression);
_extract_from_call(call_node); _extract_from_call(call_node);
@ -198,23 +203,40 @@ void GDScriptEditorTranslationParserPlugin::_assess_expression(const GDScriptPar
_assess_expression(call_node->arguments[i]); _assess_expression(call_node->arguments[i]);
} }
} break; } break;
case GDScriptParser::Node::CAST: {
_assess_expression(static_cast<const GDScriptParser::CastNode *>(p_expression)->operand);
} break;
case GDScriptParser::Node::DICTIONARY: { case GDScriptParser::Node::DICTIONARY: {
const GDScriptParser::DictionaryNode *dict_node = static_cast<const GDScriptParser::DictionaryNode *>(p_expression); const GDScriptParser::DictionaryNode *dict_node = static_cast<const GDScriptParser::DictionaryNode *>(p_expression);
for (int i = 0; i < dict_node->elements.size(); i++) { for (int i = 0; i < dict_node->elements.size(); i++) {
_assess_expression(dict_node->elements[i].key); _assess_expression(dict_node->elements[i].key);
_assess_expression(dict_node->elements[i].value); _assess_expression(dict_node->elements[i].value);
} }
break; } break;
} case GDScriptParser::Node::LAMBDA: {
_traverse_function(static_cast<const GDScriptParser::LambdaNode *>(p_expression)->function);
} break;
case GDScriptParser::Node::SUBSCRIPT: {
const GDScriptParser::SubscriptNode *subscript_node = static_cast<const GDScriptParser::SubscriptNode *>(p_expression);
_assess_expression(subscript_node->base);
if (!subscript_node->is_attribute) {
_assess_expression(subscript_node->index);
}
} break;
case GDScriptParser::Node::TERNARY_OPERATOR: { case GDScriptParser::Node::TERNARY_OPERATOR: {
const GDScriptParser::TernaryOpNode *ternary_op_node = static_cast<const GDScriptParser::TernaryOpNode *>(p_expression); const GDScriptParser::TernaryOpNode *ternary_op_node = static_cast<const GDScriptParser::TernaryOpNode *>(p_expression);
_assess_expression(ternary_op_node->condition); _assess_expression(ternary_op_node->condition);
_assess_expression(ternary_op_node->true_expr); _assess_expression(ternary_op_node->true_expr);
_assess_expression(ternary_op_node->false_expr); _assess_expression(ternary_op_node->false_expr);
break; } break;
} case GDScriptParser::Node::TYPE_TEST: {
default: _assess_expression(static_cast<const GDScriptParser::TypeTestNode *>(p_expression)->operand);
break; } break;
case GDScriptParser::Node::UNARY_OPERATOR: {
_assess_expression(static_cast<const GDScriptParser::UnaryOpNode *>(p_expression)->operand);
} break;
default: {
} break;
} }
} }

View file

@ -59,7 +59,6 @@ class GDScriptEditorTranslationParserPlugin : public EditorTranslationParserPlug
void _traverse_function(const GDScriptParser::FunctionNode *p_func); void _traverse_function(const GDScriptParser::FunctionNode *p_func);
void _traverse_block(const GDScriptParser::SuiteNode *p_suite); void _traverse_block(const GDScriptParser::SuiteNode *p_suite);
void _read_variable(const GDScriptParser::VariableNode *p_var);
void _assess_expression(const GDScriptParser::ExpressionNode *p_expression); void _assess_expression(const GDScriptParser::ExpressionNode *p_expression);
void _assess_assignment(const GDScriptParser::AssignmentNode *p_assignment); void _assess_assignment(const GDScriptParser::AssignmentNode *p_assignment);
void _extract_from_call(const GDScriptParser::CallNode *p_call); void _extract_from_call(const GDScriptParser::CallNode *p_call);