| 2851 | } |
| 2852 | |
| 2853 | void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assignment) { |
| 2854 | reduce_expression(p_assignment->assigned_value); |
| 2855 | |
| 2856 | #ifdef DEBUG_ENABLED |
| 2857 | // Increment assignment count for local variables. |
| 2858 | // Before we reduce the assignee because we don't want to warn about not being assigned when performing the assignment. |
| 2859 | if (p_assignment->assignee->type == GDScriptParser::Node::IDENTIFIER) { |
| 2860 | GDScriptParser::IdentifierNode *id = static_cast<GDScriptParser::IdentifierNode *>(p_assignment->assignee); |
| 2861 | if (id->source == GDScriptParser::IdentifierNode::LOCAL_VARIABLE && id->variable_source) { |
| 2862 | id->variable_source->assignments++; |
| 2863 | } |
| 2864 | } |
| 2865 | #endif // DEBUG_ENABLED |
| 2866 | |
| 2867 | reduce_expression(p_assignment->assignee); |
| 2868 | |
| 2869 | #ifdef DEBUG_ENABLED |
| 2870 | { |
| 2871 | bool is_subscript = false; |
| 2872 | GDScriptParser::ExpressionNode *base = p_assignment->assignee; |
| 2873 | while (base && base->type == GDScriptParser::Node::SUBSCRIPT) { |
| 2874 | is_subscript = true; |
| 2875 | base = static_cast<GDScriptParser::SubscriptNode *>(base)->base; |
| 2876 | } |
| 2877 | if (base && base->type == GDScriptParser::Node::IDENTIFIER) { |
| 2878 | GDScriptParser::IdentifierNode *id = static_cast<GDScriptParser::IdentifierNode *>(base); |
| 2879 | if (current_lambda && current_lambda->captures_indices.has(id->name)) { |
| 2880 | bool need_warn = false; |
| 2881 | if (is_subscript) { |
| 2882 | const GDScriptParser::DataType &id_type = id->datatype; |
| 2883 | if (id_type.is_hard_type()) { |
| 2884 | switch (id_type.kind) { |
| 2885 | case GDScriptParser::DataType::BUILTIN: |
| 2886 | /// @todo Change `Variant::is_type_shared()` to include packed arrays? |
| 2887 | need_warn = !Variant::is_type_shared(id_type.builtin_type) && id_type.builtin_type < Variant::PACKED_BYTE_ARRAY; |
| 2888 | break; |
| 2889 | case GDScriptParser::DataType::ENUM: |
| 2890 | need_warn = true; |
| 2891 | break; |
| 2892 | default: |
| 2893 | break; |
| 2894 | } |
| 2895 | } |
| 2896 | } else { |
| 2897 | need_warn = true; |
| 2898 | } |
| 2899 | if (need_warn) { |
| 2900 | parser->push_warning(p_assignment, GDScriptWarning::CONFUSABLE_CAPTURE_REASSIGNMENT, id->name); |
| 2901 | } |
| 2902 | } |
| 2903 | } |
| 2904 | } |
| 2905 | #endif // DEBUG_ENABLED |
| 2906 | |
| 2907 | if (p_assignment->assigned_value == nullptr || p_assignment->assignee == nullptr) { |
| 2908 | return; |
| 2909 | } |
| 2910 |
nothing calls this directly
no test coverage detected