| 3288 | } |
| 3289 | |
| 3290 | GDScriptParser::ExpressionNode *GDScriptParser::parse_attribute(ExpressionNode *p_previous_operand, bool p_can_assign) { |
| 3291 | SubscriptNode *attribute = alloc_node<SubscriptNode>(); |
| 3292 | reset_extents(attribute, p_previous_operand); |
| 3293 | update_extents(attribute); |
| 3294 | |
| 3295 | if (for_completion) { |
| 3296 | bool is_builtin = false; |
| 3297 | if (p_previous_operand && p_previous_operand->type == Node::IDENTIFIER) { |
| 3298 | const IdentifierNode *id = static_cast<const IdentifierNode *>(p_previous_operand); |
| 3299 | Variant::Type builtin_type = get_builtin_type(id->name); |
| 3300 | if (builtin_type < Variant::VARIANT_MAX) { |
| 3301 | make_completion_context(COMPLETION_BUILT_IN_TYPE_CONSTANT_OR_STATIC_METHOD, builtin_type); |
| 3302 | is_builtin = true; |
| 3303 | } |
| 3304 | } |
| 3305 | if (!is_builtin) { |
| 3306 | make_completion_context(COMPLETION_ATTRIBUTE, attribute, -1); |
| 3307 | } |
| 3308 | } |
| 3309 | |
| 3310 | attribute->base = p_previous_operand; |
| 3311 | |
| 3312 | if (current.is_node_name()) { |
| 3313 | current.type = GDScriptTokenizer::Token::IDENTIFIER; |
| 3314 | } |
| 3315 | if (!consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected identifier after "." for attribute access.)")) { |
| 3316 | complete_extents(attribute); |
| 3317 | return attribute; |
| 3318 | } |
| 3319 | |
| 3320 | attribute->is_attribute = true; |
| 3321 | attribute->attribute = parse_identifier(); |
| 3322 | |
| 3323 | complete_extents(attribute); |
| 3324 | return attribute; |
| 3325 | } |
| 3326 | |
| 3327 | GDScriptParser::ExpressionNode *GDScriptParser::parse_subscript(ExpressionNode *p_previous_operand, bool p_can_assign) { |
| 3328 | SubscriptNode *subscript = alloc_node<SubscriptNode>(); |
nothing calls this directly
no test coverage detected