| 4765 | } |
| 4766 | |
| 4767 | void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscript, bool p_can_be_pseudo_type) { |
| 4768 | if (p_subscript->base == nullptr) { |
| 4769 | return; |
| 4770 | } |
| 4771 | if (p_subscript->base->type == GDScriptParser::Node::IDENTIFIER) { |
| 4772 | reduce_identifier(static_cast<GDScriptParser::IdentifierNode *>(p_subscript->base), true); |
| 4773 | } else if (p_subscript->base->type == GDScriptParser::Node::SUBSCRIPT) { |
| 4774 | reduce_subscript(static_cast<GDScriptParser::SubscriptNode *>(p_subscript->base), true); |
| 4775 | } else { |
| 4776 | reduce_expression(p_subscript->base); |
| 4777 | } |
| 4778 | |
| 4779 | GDScriptParser::DataType result_type; |
| 4780 | |
| 4781 | if (p_subscript->is_attribute) { |
| 4782 | if (p_subscript->attribute == nullptr) { |
| 4783 | return; |
| 4784 | } |
| 4785 | |
| 4786 | GDScriptParser::DataType base_type = p_subscript->base->get_datatype(); |
| 4787 | bool valid = false; |
| 4788 | |
| 4789 | // If the base is a metatype, use the analyzer instead. |
| 4790 | if (p_subscript->base->is_constant && !base_type.is_meta_type) { |
| 4791 | // GH-92534. If the base is a GDScript, use the analyzer instead. |
| 4792 | bool base_is_gdscript = false; |
| 4793 | if (p_subscript->base->reduced_value.get_type() == Variant::OBJECT) { |
| 4794 | Ref<GDScript> gdscript = Object::cast_to<GDScript>(p_subscript->base->reduced_value.get_validated_object()); |
| 4795 | if (gdscript.is_valid()) { |
| 4796 | base_is_gdscript = true; |
| 4797 | // Makes a metatype from a constant GDScript, since `base_type` is not a metatype. |
| 4798 | GDScriptParser::DataType base_type_meta = type_from_variant(gdscript, p_subscript); |
| 4799 | // First try to reduce the attribute from the metatype. |
| 4800 | reduce_identifier_from_base(p_subscript->attribute, &base_type_meta); |
| 4801 | GDScriptParser::DataType attr_type = p_subscript->attribute->get_datatype(); |
| 4802 | if (attr_type.is_set()) { |
| 4803 | valid = !attr_type.is_pseudo_type || p_can_be_pseudo_type; |
| 4804 | result_type = attr_type; |
| 4805 | p_subscript->is_constant = p_subscript->attribute->is_constant; |
| 4806 | p_subscript->reduced_value = p_subscript->attribute->reduced_value; |
| 4807 | } |
| 4808 | if (!valid) { |
| 4809 | // If unsuccessful, reset and return to the normal route. |
| 4810 | p_subscript->attribute->set_datatype(GDScriptParser::DataType()); |
| 4811 | } |
| 4812 | } |
| 4813 | } |
| 4814 | if (!base_is_gdscript) { |
| 4815 | // Just try to get it. |
| 4816 | Variant value = p_subscript->base->reduced_value.get_named(p_subscript->attribute->name, valid); |
| 4817 | if (valid) { |
| 4818 | p_subscript->is_constant = true; |
| 4819 | p_subscript->reduced_value = value; |
| 4820 | result_type = type_from_variant(value, p_subscript); |
| 4821 | } |
| 4822 | } |
| 4823 | } |
| 4824 |
nothing calls this directly
no test coverage detected