mirror of
				https://github.com/godotengine/godot.git
				synced 2025-11-03 23:21:15 +00:00 
			
		
		
		
	Fix completion popup for the variables created with get_node call
				
					
				
			This commit is contained in:
		
							parent
							
								
									315c64282b
								
							
						
					
					
						commit
						65d14679e7
					
				
					 1 changed files with 63 additions and 61 deletions
				
			
		| 
						 | 
				
			
			@ -2511,6 +2511,57 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool _get_subscript_type(GDScriptParser::CompletionContext &p_context, const GDScriptParser::SubscriptNode *p_subscript, GDScriptParser::DataType &r_base_type, Variant *r_base = nullptr) {
 | 
			
		||||
	if (p_subscript->base->type == GDScriptParser::Node::IDENTIFIER) {
 | 
			
		||||
		const GDScriptParser::GetNodeNode *get_node = nullptr;
 | 
			
		||||
		const GDScriptParser::IdentifierNode *identifier_node = static_cast<GDScriptParser::IdentifierNode *>(p_subscript->base);
 | 
			
		||||
 | 
			
		||||
		switch (identifier_node->source) {
 | 
			
		||||
			case GDScriptParser::IdentifierNode::Source::MEMBER_VARIABLE: {
 | 
			
		||||
				if (p_context.current_class != nullptr) {
 | 
			
		||||
					const StringName &member_name = identifier_node->name;
 | 
			
		||||
					const GDScriptParser::ClassNode *current_class = p_context.current_class;
 | 
			
		||||
 | 
			
		||||
					if (current_class->has_member(member_name)) {
 | 
			
		||||
						const GDScriptParser::ClassNode::Member &member = current_class->get_member(member_name);
 | 
			
		||||
 | 
			
		||||
						if (member.type == GDScriptParser::ClassNode::Member::VARIABLE) {
 | 
			
		||||
							const GDScriptParser::VariableNode *variable = static_cast<GDScriptParser::VariableNode *>(member.variable);
 | 
			
		||||
 | 
			
		||||
							if (variable->initializer && variable->initializer->type == GDScriptParser::Node::GET_NODE) {
 | 
			
		||||
								get_node = static_cast<GDScriptParser::GetNodeNode *>(variable->initializer);
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			} break;
 | 
			
		||||
			case GDScriptParser::IdentifierNode::Source::LOCAL_VARIABLE: {
 | 
			
		||||
				if (identifier_node->next != nullptr && identifier_node->next->type == GDScriptParser::ClassNode::Node::GET_NODE) {
 | 
			
		||||
					get_node = static_cast<GDScriptParser::GetNodeNode *>(identifier_node->next);
 | 
			
		||||
				}
 | 
			
		||||
			} break;
 | 
			
		||||
			default:
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (get_node != nullptr) {
 | 
			
		||||
			const Object *node = p_context.base->call("get_node_or_null", NodePath(get_node->full_path));
 | 
			
		||||
			if (node != nullptr) {
 | 
			
		||||
				if (r_base != nullptr) {
 | 
			
		||||
					*r_base = node;
 | 
			
		||||
				}
 | 
			
		||||
				r_base_type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
 | 
			
		||||
				r_base_type.kind = GDScriptParser::DataType::NATIVE;
 | 
			
		||||
				r_base_type.native_type = node->get_class_name();
 | 
			
		||||
				r_base_type.builtin_type = Variant::OBJECT;
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, const GDScriptParser::Node *p_call, int p_argidx, HashMap<String, ScriptLanguage::CodeCompletionOption> &r_result, bool &r_forced, String &r_arghint) {
 | 
			
		||||
	if (p_call->type == GDScriptParser::Node::PRELOAD) {
 | 
			
		||||
		if (p_argidx == 0 && bool(EDITOR_GET("text_editor/completion/complete_file_paths"))) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2561,13 +2612,17 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
 | 
			
		|||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (subscript->is_attribute) {
 | 
			
		||||
			GDScriptCompletionIdentifier ci;
 | 
			
		||||
			if (_guess_expression_type(p_context, subscript->base, ci)) {
 | 
			
		||||
				base_type = ci.type;
 | 
			
		||||
				base = ci.value;
 | 
			
		||||
			} else {
 | 
			
		||||
				return;
 | 
			
		||||
		if (p_context.base != nullptr && subscript->is_attribute) {
 | 
			
		||||
			bool found_type = _get_subscript_type(p_context, subscript, base_type, &base);
 | 
			
		||||
 | 
			
		||||
			if (!found_type) {
 | 
			
		||||
				GDScriptCompletionIdentifier ci;
 | 
			
		||||
				if (_guess_expression_type(p_context, subscript->base, ci)) {
 | 
			
		||||
					base_type = ci.type;
 | 
			
		||||
					base = ci.value;
 | 
			
		||||
				} else {
 | 
			
		||||
					return;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			_static = base_type.is_meta_type;
 | 
			
		||||
| 
						 | 
				
			
			@ -2765,60 +2820,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
 | 
			
		|||
			const GDScriptParser::SubscriptNode *attr = static_cast<const GDScriptParser::SubscriptNode *>(completion_context.node);
 | 
			
		||||
			if (attr->base) {
 | 
			
		||||
				GDScriptCompletionIdentifier base;
 | 
			
		||||
				bool found_type = false;
 | 
			
		||||
 | 
			
		||||
				if (p_owner != nullptr && attr->base->type == GDScriptParser::Node::IDENTIFIER) {
 | 
			
		||||
					const GDScriptParser::GetNodeNode *get_node = nullptr;
 | 
			
		||||
					const GDScriptParser::IdentifierNode *identifier_node = static_cast<GDScriptParser::IdentifierNode *>(attr->base);
 | 
			
		||||
 | 
			
		||||
					switch (identifier_node->source) {
 | 
			
		||||
						case GDScriptParser::IdentifierNode::Source::MEMBER_VARIABLE: {
 | 
			
		||||
							if (completion_context.current_class != nullptr) {
 | 
			
		||||
								const StringName &member_name = identifier_node->name;
 | 
			
		||||
								const GDScriptParser::ClassNode *current_class = completion_context.current_class;
 | 
			
		||||
 | 
			
		||||
								if (current_class->has_member(member_name)) {
 | 
			
		||||
									const GDScriptParser::ClassNode::Member &member = current_class->get_member(member_name);
 | 
			
		||||
 | 
			
		||||
									if (member.type == GDScriptParser::ClassNode::Member::VARIABLE) {
 | 
			
		||||
										const GDScriptParser::VariableNode *variable = static_cast<GDScriptParser::VariableNode *>(member.variable);
 | 
			
		||||
 | 
			
		||||
										if (variable->initializer && variable->initializer->type == GDScriptParser::Node::GET_NODE) {
 | 
			
		||||
											get_node = static_cast<GDScriptParser::GetNodeNode *>(variable->initializer);
 | 
			
		||||
										}
 | 
			
		||||
									}
 | 
			
		||||
								}
 | 
			
		||||
							}
 | 
			
		||||
						} break;
 | 
			
		||||
						case GDScriptParser::IdentifierNode::Source::LOCAL_VARIABLE: {
 | 
			
		||||
							if (identifier_node->next != nullptr && identifier_node->next->type == GDScriptParser::ClassNode::Node::GET_NODE) {
 | 
			
		||||
								get_node = static_cast<GDScriptParser::GetNodeNode *>(identifier_node->next);
 | 
			
		||||
							}
 | 
			
		||||
						} break;
 | 
			
		||||
						default:
 | 
			
		||||
							break;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if (get_node != nullptr) {
 | 
			
		||||
						const Object *node = p_owner->call("get_node_or_null", NodePath(get_node->full_path));
 | 
			
		||||
						if (node != nullptr) {
 | 
			
		||||
							found_type = true;
 | 
			
		||||
 | 
			
		||||
							GDScriptParser::DataType type;
 | 
			
		||||
							type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
 | 
			
		||||
							type.kind = GDScriptParser::DataType::NATIVE;
 | 
			
		||||
							type.native_type = node->get_class_name();
 | 
			
		||||
							type.builtin_type = Variant::OBJECT;
 | 
			
		||||
 | 
			
		||||
							base.type = type;
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						if (!found_type) {
 | 
			
		||||
							break;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				bool found_type = _get_subscript_type(completion_context, attr, base.type);
 | 
			
		||||
				if (!found_type && !_guess_expression_type(completion_context, attr->base, base)) {
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue